1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2014 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * Tests for firmware image library.
6*8617a60dSAndroid Build Coastguard Worker */
7*8617a60dSAndroid Build Coastguard Worker
8*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
9*8617a60dSAndroid Build Coastguard Worker
10*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
13*8617a60dSAndroid Build Coastguard Worker #include "common/tests.h"
14*8617a60dSAndroid Build Coastguard Worker #include "file_keys.h"
15*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
16*8617a60dSAndroid Build Coastguard Worker #include "host_keyblock.h"
17*8617a60dSAndroid Build Coastguard Worker #include "host_key.h"
18*8617a60dSAndroid Build Coastguard Worker #include "host_signature.h"
19*8617a60dSAndroid Build Coastguard Worker
resign_keyblock(struct vb2_keyblock * h,const struct vb2_private_key * key)20*8617a60dSAndroid Build Coastguard Worker static void resign_keyblock(struct vb2_keyblock *h,
21*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *key)
22*8617a60dSAndroid Build Coastguard Worker {
23*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig =
24*8617a60dSAndroid Build Coastguard Worker vb2_calculate_signature((const uint8_t *)h,
25*8617a60dSAndroid Build Coastguard Worker h->keyblock_signature.data_size, key);
26*8617a60dSAndroid Build Coastguard Worker
27*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->keyblock_signature, sig);
28*8617a60dSAndroid Build Coastguard Worker free(sig);
29*8617a60dSAndroid Build Coastguard Worker }
30*8617a60dSAndroid Build Coastguard Worker
test_check_keyblock(const struct vb2_public_key * public_key,const struct vb2_private_key * private_key,const struct vb2_packed_key * data_key)31*8617a60dSAndroid Build Coastguard Worker static void test_check_keyblock(const struct vb2_public_key *public_key,
32*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *private_key,
33*8617a60dSAndroid Build Coastguard Worker const struct vb2_packed_key *data_key)
34*8617a60dSAndroid Build Coastguard Worker {
35*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *hdr;
36*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *h;
37*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig;
38*8617a60dSAndroid Build Coastguard Worker uint32_t hsize;
39*8617a60dSAndroid Build Coastguard Worker
40*8617a60dSAndroid Build Coastguard Worker hdr = vb2_create_keyblock(data_key, private_key, 0x1234);
41*8617a60dSAndroid Build Coastguard Worker TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites");
42*8617a60dSAndroid Build Coastguard Worker if (!hdr)
43*8617a60dSAndroid Build Coastguard Worker return;
44*8617a60dSAndroid Build Coastguard Worker hsize = hdr->keyblock_size;
45*8617a60dSAndroid Build Coastguard Worker h = (struct vb2_keyblock *)malloc(hsize + 2048);
46*8617a60dSAndroid Build Coastguard Worker sig = &h->keyblock_signature;
47*8617a60dSAndroid Build Coastguard Worker
48*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
49*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
50*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() ok");
51*8617a60dSAndroid Build Coastguard Worker
52*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
53*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize - 1, sig),
54*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIZE, "vb2_check_keyblock() size--");
55*8617a60dSAndroid Build Coastguard Worker
56*8617a60dSAndroid Build Coastguard Worker /* Buffer is allowed to be bigger than keyblock */
57*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
58*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_check_keyblock(h, hsize + 1, sig),
59*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() size++");
60*8617a60dSAndroid Build Coastguard Worker
61*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
62*8617a60dSAndroid Build Coastguard Worker h->magic[0] &= 0x12;
63*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
64*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_MAGIC, "vb2_check_keyblock() magic");
65*8617a60dSAndroid Build Coastguard Worker
66*8617a60dSAndroid Build Coastguard Worker /* Care about major version but not minor */
67*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
68*8617a60dSAndroid Build Coastguard Worker h->header_version_major++;
69*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
70*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
71*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_HEADER_VERSION,
72*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() major++");
73*8617a60dSAndroid Build Coastguard Worker
74*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
75*8617a60dSAndroid Build Coastguard Worker h->header_version_major--;
76*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
77*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
78*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_HEADER_VERSION,
79*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() major--");
80*8617a60dSAndroid Build Coastguard Worker
81*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
82*8617a60dSAndroid Build Coastguard Worker h->header_version_minor++;
83*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
84*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
85*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() minor++");
86*8617a60dSAndroid Build Coastguard Worker
87*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
88*8617a60dSAndroid Build Coastguard Worker h->header_version_minor--;
89*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
90*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
91*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() minor--");
92*8617a60dSAndroid Build Coastguard Worker
93*8617a60dSAndroid Build Coastguard Worker /* Check signature */
94*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
95*8617a60dSAndroid Build Coastguard Worker h->keyblock_signature.sig_offset = hsize;
96*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
97*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
98*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIG_OUTSIDE,
99*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() sig off end");
100*8617a60dSAndroid Build Coastguard Worker
101*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
102*8617a60dSAndroid Build Coastguard Worker h->keyblock_signature.data_size = h->keyblock_size + 1;
103*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
104*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH,
105*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() sig data past end of block");
106*8617a60dSAndroid Build Coastguard Worker
107*8617a60dSAndroid Build Coastguard Worker /* Check that we signed header and data key */
108*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
109*8617a60dSAndroid Build Coastguard Worker h->keyblock_signature.data_size = 4;
110*8617a60dSAndroid Build Coastguard Worker h->data_key.key_offset = 0;
111*8617a60dSAndroid Build Coastguard Worker h->data_key.key_size = 0;
112*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
113*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
114*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE,
115*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() didn't sign header");
116*8617a60dSAndroid Build Coastguard Worker
117*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
118*8617a60dSAndroid Build Coastguard Worker h->data_key.key_offset = hsize;
119*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
120*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(h, hsize, sig),
121*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE,
122*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock() data key off end");
123*8617a60dSAndroid Build Coastguard Worker
124*8617a60dSAndroid Build Coastguard Worker /* Corner cases for error checking */
125*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_check_keyblock(NULL, 4, sig),
126*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER,
127*8617a60dSAndroid Build Coastguard Worker "vb2_check_keyblock size too small");
128*8617a60dSAndroid Build Coastguard Worker
129*8617a60dSAndroid Build Coastguard Worker /*
130*8617a60dSAndroid Build Coastguard Worker * TODO: verify parser can support a bigger header (i.e., one where
131*8617a60dSAndroid Build Coastguard Worker * data_key.key_offset is bigger than expected).
132*8617a60dSAndroid Build Coastguard Worker */
133*8617a60dSAndroid Build Coastguard Worker
134*8617a60dSAndroid Build Coastguard Worker free(h);
135*8617a60dSAndroid Build Coastguard Worker free(hdr);
136*8617a60dSAndroid Build Coastguard Worker }
137*8617a60dSAndroid Build Coastguard Worker
test_verify_keyblock(const struct vb2_public_key * public_key,const struct vb2_private_key * private_key,const struct vb2_packed_key * data_key)138*8617a60dSAndroid Build Coastguard Worker static void test_verify_keyblock(const struct vb2_public_key *public_key,
139*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *private_key,
140*8617a60dSAndroid Build Coastguard Worker const struct vb2_packed_key *data_key)
141*8617a60dSAndroid Build Coastguard Worker {
142*8617a60dSAndroid Build Coastguard Worker uint8_t workbuf[VB2_KEYBLOCK_VERIFY_WORKBUF_BYTES]
143*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
144*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
145*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *hdr;
146*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *h;
147*8617a60dSAndroid Build Coastguard Worker uint32_t hsize;
148*8617a60dSAndroid Build Coastguard Worker
149*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
150*8617a60dSAndroid Build Coastguard Worker
151*8617a60dSAndroid Build Coastguard Worker hdr = vb2_create_keyblock(data_key, private_key, 0x1234);
152*8617a60dSAndroid Build Coastguard Worker TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites");
153*8617a60dSAndroid Build Coastguard Worker if (!hdr)
154*8617a60dSAndroid Build Coastguard Worker return;
155*8617a60dSAndroid Build Coastguard Worker hsize = hdr->keyblock_size;
156*8617a60dSAndroid Build Coastguard Worker h = (struct vb2_keyblock *)malloc(hsize + 2048);
157*8617a60dSAndroid Build Coastguard Worker
158*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
159*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_keyblock(h, hsize, public_key, &wb),
160*8617a60dSAndroid Build Coastguard Worker "vb2_verify_keyblock() ok using key");
161*8617a60dSAndroid Build Coastguard Worker
162*8617a60dSAndroid Build Coastguard Worker /* Failures in keyblock check also cause verify to fail */
163*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
164*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_keyblock(h, hsize - 1, public_key, &wb),
165*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIZE, "vb2_verify_keyblock() check");
166*8617a60dSAndroid Build Coastguard Worker
167*8617a60dSAndroid Build Coastguard Worker /* Check signature */
168*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
169*8617a60dSAndroid Build Coastguard Worker h->keyblock_signature.sig_size--;
170*8617a60dSAndroid Build Coastguard Worker resign_keyblock(h, private_key);
171*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb),
172*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIG_INVALID,
173*8617a60dSAndroid Build Coastguard Worker "vb2_verify_keyblock() sig too small");
174*8617a60dSAndroid Build Coastguard Worker
175*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
176*8617a60dSAndroid Build Coastguard Worker ((uint8_t *)vb2_packed_key_data_mutable(&h->data_key))[0] ^= 0x34;
177*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb),
178*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_KEYBLOCK_SIG_INVALID,
179*8617a60dSAndroid Build Coastguard Worker "vb2_verify_keyblock() sig mismatch");
180*8617a60dSAndroid Build Coastguard Worker
181*8617a60dSAndroid Build Coastguard Worker /*
182*8617a60dSAndroid Build Coastguard Worker * TODO: verify parser can support a bigger header (i.e., one where
183*8617a60dSAndroid Build Coastguard Worker * data_key.key_offset is bigger than expected).
184*8617a60dSAndroid Build Coastguard Worker */
185*8617a60dSAndroid Build Coastguard Worker
186*8617a60dSAndroid Build Coastguard Worker free(h);
187*8617a60dSAndroid Build Coastguard Worker free(hdr);
188*8617a60dSAndroid Build Coastguard Worker }
189*8617a60dSAndroid Build Coastguard Worker
resign_fw_preamble(struct vb2_fw_preamble * h,struct vb2_private_key * key)190*8617a60dSAndroid Build Coastguard Worker static void resign_fw_preamble(struct vb2_fw_preamble *h,
191*8617a60dSAndroid Build Coastguard Worker struct vb2_private_key *key)
192*8617a60dSAndroid Build Coastguard Worker {
193*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig = vb2_calculate_signature(
194*8617a60dSAndroid Build Coastguard Worker (const uint8_t *)h, h->preamble_signature.data_size, key);
195*8617a60dSAndroid Build Coastguard Worker
196*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->preamble_signature, sig);
197*8617a60dSAndroid Build Coastguard Worker free(sig);
198*8617a60dSAndroid Build Coastguard Worker }
199*8617a60dSAndroid Build Coastguard Worker
test_verify_fw_preamble(struct vb2_packed_key * public_key,struct vb2_private_key * private_key,struct vb2_packed_key * kernel_subkey)200*8617a60dSAndroid Build Coastguard Worker static void test_verify_fw_preamble(struct vb2_packed_key *public_key,
201*8617a60dSAndroid Build Coastguard Worker struct vb2_private_key *private_key,
202*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *kernel_subkey)
203*8617a60dSAndroid Build Coastguard Worker {
204*8617a60dSAndroid Build Coastguard Worker struct vb2_fw_preamble *hdr;
205*8617a60dSAndroid Build Coastguard Worker struct vb2_fw_preamble *h;
206*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key rsa;
207*8617a60dSAndroid Build Coastguard Worker uint8_t workbuf[VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES]
208*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
209*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
210*8617a60dSAndroid Build Coastguard Worker uint32_t hsize;
211*8617a60dSAndroid Build Coastguard Worker
212*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
213*8617a60dSAndroid Build Coastguard Worker
214*8617a60dSAndroid Build Coastguard Worker /* Create a dummy signature */
215*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *body_sig = vb2_alloc_signature(56, 78);
216*8617a60dSAndroid Build Coastguard Worker
217*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_unpack_key(&rsa, public_key),
218*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() prereq key");
219*8617a60dSAndroid Build Coastguard Worker
220*8617a60dSAndroid Build Coastguard Worker hdr = vb2_create_fw_preamble(0x1234, kernel_subkey, body_sig,
221*8617a60dSAndroid Build Coastguard Worker private_key, 0x5678);
222*8617a60dSAndroid Build Coastguard Worker TEST_PTR_NEQ(hdr, NULL,
223*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() prereq test preamble");
224*8617a60dSAndroid Build Coastguard Worker if (!hdr) {
225*8617a60dSAndroid Build Coastguard Worker free(body_sig);
226*8617a60dSAndroid Build Coastguard Worker return;
227*8617a60dSAndroid Build Coastguard Worker }
228*8617a60dSAndroid Build Coastguard Worker
229*8617a60dSAndroid Build Coastguard Worker hsize = (uint32_t) hdr->preamble_size;
230*8617a60dSAndroid Build Coastguard Worker h = (struct vb2_fw_preamble *)malloc(hsize + 16384);
231*8617a60dSAndroid Build Coastguard Worker
232*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
233*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
234*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() ok using key");
235*8617a60dSAndroid Build Coastguard Worker
236*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
237*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, 4, &rsa, &wb),
238*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
239*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() size tiny");
240*8617a60dSAndroid Build Coastguard Worker
241*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
242*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize - 1, &rsa, &wb),
243*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIZE,
244*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() size--");
245*8617a60dSAndroid Build Coastguard Worker
246*8617a60dSAndroid Build Coastguard Worker /* Buffer is allowed to be bigger than preamble */
247*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
248*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_fw_preamble(h, hsize + 1, &rsa, &wb),
249*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() size++");
250*8617a60dSAndroid Build Coastguard Worker
251*8617a60dSAndroid Build Coastguard Worker /* Care about major version but not minor */
252*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
253*8617a60dSAndroid Build Coastguard Worker h->header_version_major++;
254*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
255*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
256*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_HEADER_VERSION
257*8617a60dSAndroid Build Coastguard Worker , "vb2_verify_fw_preamble() major++");
258*8617a60dSAndroid Build Coastguard Worker
259*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
260*8617a60dSAndroid Build Coastguard Worker h->header_version_major--;
261*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
262*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
263*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_HEADER_VERSION,
264*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() major--");
265*8617a60dSAndroid Build Coastguard Worker
266*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
267*8617a60dSAndroid Build Coastguard Worker h->header_version_minor++;
268*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
269*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
270*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() minor++");
271*8617a60dSAndroid Build Coastguard Worker
272*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
273*8617a60dSAndroid Build Coastguard Worker h->header_version_minor--;
274*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
275*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
276*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_HEADER_OLD,
277*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() 2.0 not supported");
278*8617a60dSAndroid Build Coastguard Worker
279*8617a60dSAndroid Build Coastguard Worker /* Check signature */
280*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
281*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.sig_offset = hsize;
282*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
283*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
284*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
285*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() sig off end");
286*8617a60dSAndroid Build Coastguard Worker
287*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
288*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.sig_size--;
289*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
290*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
291*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_INVALID,
292*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() sig too small");
293*8617a60dSAndroid Build Coastguard Worker
294*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
295*8617a60dSAndroid Build Coastguard Worker ((uint8_t *)vb2_packed_key_data_mutable(&h->kernel_subkey))[0] ^= 0x34;
296*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
297*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_INVALID,
298*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() sig mismatch");
299*8617a60dSAndroid Build Coastguard Worker
300*8617a60dSAndroid Build Coastguard Worker /* Check that we signed header, kernel subkey, and body sig */
301*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
302*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.data_size = 4;
303*8617a60dSAndroid Build Coastguard Worker h->kernel_subkey.key_offset = 0;
304*8617a60dSAndroid Build Coastguard Worker h->kernel_subkey.key_size = 0;
305*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_offset = 0;
306*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_size = 0;
307*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
308*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
309*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
310*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() didn't sign header");
311*8617a60dSAndroid Build Coastguard Worker
312*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
313*8617a60dSAndroid Build Coastguard Worker h->kernel_subkey.key_offset = hsize;
314*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
315*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
316*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE,
317*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() kernel subkey off end");
318*8617a60dSAndroid Build Coastguard Worker
319*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
320*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_offset = hsize;
321*8617a60dSAndroid Build Coastguard Worker resign_fw_preamble(h, private_key);
322*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
323*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
324*8617a60dSAndroid Build Coastguard Worker "vb2_verify_fw_preamble() body sig off end");
325*8617a60dSAndroid Build Coastguard Worker
326*8617a60dSAndroid Build Coastguard Worker /* TODO: verify with extra padding at end of header. */
327*8617a60dSAndroid Build Coastguard Worker
328*8617a60dSAndroid Build Coastguard Worker free(h);
329*8617a60dSAndroid Build Coastguard Worker free(hdr);
330*8617a60dSAndroid Build Coastguard Worker free(body_sig);
331*8617a60dSAndroid Build Coastguard Worker }
332*8617a60dSAndroid Build Coastguard Worker
resign_kernel_preamble(struct vb2_kernel_preamble * h,const struct vb2_private_key * key)333*8617a60dSAndroid Build Coastguard Worker static void resign_kernel_preamble(struct vb2_kernel_preamble *h,
334*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *key)
335*8617a60dSAndroid Build Coastguard Worker {
336*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig = vb2_calculate_signature(
337*8617a60dSAndroid Build Coastguard Worker (const uint8_t *)h, h->preamble_signature.data_size, key);
338*8617a60dSAndroid Build Coastguard Worker
339*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->preamble_signature, sig);
340*8617a60dSAndroid Build Coastguard Worker free(sig);
341*8617a60dSAndroid Build Coastguard Worker }
342*8617a60dSAndroid Build Coastguard Worker
test_verify_kernel_preamble(const struct vb2_packed_key * public_key,const struct vb2_private_key * private_key)343*8617a60dSAndroid Build Coastguard Worker static void test_verify_kernel_preamble(
344*8617a60dSAndroid Build Coastguard Worker const struct vb2_packed_key *public_key,
345*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *private_key)
346*8617a60dSAndroid Build Coastguard Worker {
347*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key rsa;
348*8617a60dSAndroid Build Coastguard Worker // TODO: how many workbuf bytes?
349*8617a60dSAndroid Build Coastguard Worker uint8_t workbuf[VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES]
350*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
351*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
352*8617a60dSAndroid Build Coastguard Worker uint32_t hsize;
353*8617a60dSAndroid Build Coastguard Worker
354*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
355*8617a60dSAndroid Build Coastguard Worker
356*8617a60dSAndroid Build Coastguard Worker /* Create a dummy signature */
357*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *body_sig = vb2_alloc_signature(56, 0x214000);
358*8617a60dSAndroid Build Coastguard Worker
359*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_unpack_key(&rsa, public_key),
360*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() prereq key");
361*8617a60dSAndroid Build Coastguard Worker
362*8617a60dSAndroid Build Coastguard Worker struct vb2_kernel_preamble *hdr =
363*8617a60dSAndroid Build Coastguard Worker vb2_create_kernel_preamble(0x1234, 0x100000, 0x300000, 0x4000,
364*8617a60dSAndroid Build Coastguard Worker body_sig, 0x304000, 0x10000, 0, 0,
365*8617a60dSAndroid Build Coastguard Worker private_key);
366*8617a60dSAndroid Build Coastguard Worker TEST_PTR_NEQ(hdr, NULL,
367*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() prereq test preamble");
368*8617a60dSAndroid Build Coastguard Worker if (!hdr) {
369*8617a60dSAndroid Build Coastguard Worker free(body_sig);
370*8617a60dSAndroid Build Coastguard Worker return;
371*8617a60dSAndroid Build Coastguard Worker }
372*8617a60dSAndroid Build Coastguard Worker
373*8617a60dSAndroid Build Coastguard Worker hsize = (uint32_t) hdr->preamble_size;
374*8617a60dSAndroid Build Coastguard Worker struct vb2_kernel_preamble *h =
375*8617a60dSAndroid Build Coastguard Worker (struct vb2_kernel_preamble *)malloc(hsize + 16384);
376*8617a60dSAndroid Build Coastguard Worker
377*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
378*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
379*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() ok using key");
380*8617a60dSAndroid Build Coastguard Worker
381*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
382*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, 4, &rsa, &wb),
383*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
384*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() size tiny");
385*8617a60dSAndroid Build Coastguard Worker
386*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
387*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize - 1, &rsa, &wb),
388*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIZE,
389*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() size--");
390*8617a60dSAndroid Build Coastguard Worker
391*8617a60dSAndroid Build Coastguard Worker /* Buffer is allowed to be bigger than preamble */
392*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
393*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_kernel_preamble(h, hsize + 1, &rsa, &wb),
394*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() size++");
395*8617a60dSAndroid Build Coastguard Worker
396*8617a60dSAndroid Build Coastguard Worker /* Care about major version but not minor */
397*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
398*8617a60dSAndroid Build Coastguard Worker h->header_version_major++;
399*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
400*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
401*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_HEADER_VERSION
402*8617a60dSAndroid Build Coastguard Worker , "vb2_verify_kernel_preamble() major++");
403*8617a60dSAndroid Build Coastguard Worker
404*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
405*8617a60dSAndroid Build Coastguard Worker h->header_version_major--;
406*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
407*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
408*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_HEADER_VERSION,
409*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() major--");
410*8617a60dSAndroid Build Coastguard Worker
411*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
412*8617a60dSAndroid Build Coastguard Worker h->header_version_minor++;
413*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
414*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
415*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() minor++");
416*8617a60dSAndroid Build Coastguard Worker
417*8617a60dSAndroid Build Coastguard Worker /* Check signature */
418*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
419*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.sig_offset = hsize;
420*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
421*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
422*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
423*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() sig off end");
424*8617a60dSAndroid Build Coastguard Worker
425*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
426*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.sig_size--;
427*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
428*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
429*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_INVALID,
430*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() sig too small");
431*8617a60dSAndroid Build Coastguard Worker
432*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
433*8617a60dSAndroid Build Coastguard Worker h->flags++;
434*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
435*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIG_INVALID,
436*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() sig mismatch");
437*8617a60dSAndroid Build Coastguard Worker
438*8617a60dSAndroid Build Coastguard Worker /* Check that we signed header and body sig */
439*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
440*8617a60dSAndroid Build Coastguard Worker h->preamble_signature.data_size = 4;
441*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_offset = 0;
442*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_size = 0;
443*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
444*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
445*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
446*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() didn't sign header");
447*8617a60dSAndroid Build Coastguard Worker
448*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
449*8617a60dSAndroid Build Coastguard Worker h->body_signature.sig_offset = hsize;
450*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
451*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
452*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
453*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() body sig off end");
454*8617a60dSAndroid Build Coastguard Worker
455*8617a60dSAndroid Build Coastguard Worker /* Check bootloader inside signed body */
456*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
457*8617a60dSAndroid Build Coastguard Worker h->bootloader_address = h->body_load_address - 1;
458*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
459*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
460*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE,
461*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() bootloader before body");
462*8617a60dSAndroid Build Coastguard Worker
463*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
464*8617a60dSAndroid Build Coastguard Worker h->bootloader_address = h->body_load_address +
465*8617a60dSAndroid Build Coastguard Worker h->body_signature.data_size + 1;
466*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
467*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
468*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE,
469*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() bootloader off end of body");
470*8617a60dSAndroid Build Coastguard Worker
471*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
472*8617a60dSAndroid Build Coastguard Worker h->bootloader_address = h->body_load_address +
473*8617a60dSAndroid Build Coastguard Worker h->body_signature.data_size + 1;
474*8617a60dSAndroid Build Coastguard Worker h->bootloader_size = 0;
475*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
476*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
477*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() no bootloader");
478*8617a60dSAndroid Build Coastguard Worker
479*8617a60dSAndroid Build Coastguard Worker /* Check vmlinuz inside signed body */
480*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
481*8617a60dSAndroid Build Coastguard Worker h->vmlinuz_header_address = h->body_load_address - 1;
482*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
483*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
484*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE,
485*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() vmlinuz_header before body");
486*8617a60dSAndroid Build Coastguard Worker
487*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
488*8617a60dSAndroid Build Coastguard Worker h->vmlinuz_header_address = h->body_load_address +
489*8617a60dSAndroid Build Coastguard Worker h->body_signature.data_size + 1;
490*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
491*8617a60dSAndroid Build Coastguard Worker TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
492*8617a60dSAndroid Build Coastguard Worker VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE,
493*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() vmlinuz_header off end of body");
494*8617a60dSAndroid Build Coastguard Worker
495*8617a60dSAndroid Build Coastguard Worker memcpy(h, hdr, hsize);
496*8617a60dSAndroid Build Coastguard Worker h->vmlinuz_header_address = h->body_load_address +
497*8617a60dSAndroid Build Coastguard Worker h->body_signature.data_size + 1;
498*8617a60dSAndroid Build Coastguard Worker h->vmlinuz_header_size = 0;
499*8617a60dSAndroid Build Coastguard Worker resign_kernel_preamble(h, private_key);
500*8617a60dSAndroid Build Coastguard Worker TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
501*8617a60dSAndroid Build Coastguard Worker "vb2_verify_kernel_preamble() no vmlinuz_header");
502*8617a60dSAndroid Build Coastguard Worker
503*8617a60dSAndroid Build Coastguard Worker /* TODO: verify with extra padding at end of header. */
504*8617a60dSAndroid Build Coastguard Worker
505*8617a60dSAndroid Build Coastguard Worker free(h);
506*8617a60dSAndroid Build Coastguard Worker free(hdr);
507*8617a60dSAndroid Build Coastguard Worker free(body_sig);
508*8617a60dSAndroid Build Coastguard Worker }
509*8617a60dSAndroid Build Coastguard Worker
test_permutation(int signing_key_algorithm,int data_key_algorithm,const char * keys_dir)510*8617a60dSAndroid Build Coastguard Worker static int test_permutation(int signing_key_algorithm, int data_key_algorithm,
511*8617a60dSAndroid Build Coastguard Worker const char *keys_dir)
512*8617a60dSAndroid Build Coastguard Worker {
513*8617a60dSAndroid Build Coastguard Worker char filename[1024];
514*8617a60dSAndroid Build Coastguard Worker int retval = 1;
515*8617a60dSAndroid Build Coastguard Worker
516*8617a60dSAndroid Build Coastguard Worker struct vb2_private_key *signing_private_key = NULL;
517*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *signing_public_key = NULL;
518*8617a60dSAndroid Build Coastguard Worker struct vb2_packed_key *data_public_key = NULL;
519*8617a60dSAndroid Build Coastguard Worker
520*8617a60dSAndroid Build Coastguard Worker printf("***Testing signing algorithm: %s\n",
521*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_name(signing_key_algorithm));
522*8617a60dSAndroid Build Coastguard Worker printf("***With data key algorithm: %s\n",
523*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_name(data_key_algorithm));
524*8617a60dSAndroid Build Coastguard Worker
525*8617a60dSAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/key_%s.pem",
526*8617a60dSAndroid Build Coastguard Worker keys_dir,
527*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_file(signing_key_algorithm));
528*8617a60dSAndroid Build Coastguard Worker signing_private_key =
529*8617a60dSAndroid Build Coastguard Worker vb2_read_private_key_pem(filename, signing_key_algorithm);
530*8617a60dSAndroid Build Coastguard Worker if (!signing_private_key) {
531*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Error reading signing_private_key: %s\n",
532*8617a60dSAndroid Build Coastguard Worker filename);
533*8617a60dSAndroid Build Coastguard Worker goto cleanup_permutation;
534*8617a60dSAndroid Build Coastguard Worker }
535*8617a60dSAndroid Build Coastguard Worker
536*8617a60dSAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/key_%s.keyb",
537*8617a60dSAndroid Build Coastguard Worker keys_dir,
538*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_file(signing_key_algorithm));
539*8617a60dSAndroid Build Coastguard Worker signing_public_key =
540*8617a60dSAndroid Build Coastguard Worker vb2_read_packed_keyb(filename, signing_key_algorithm, 1);
541*8617a60dSAndroid Build Coastguard Worker if (!signing_public_key) {
542*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Error reading signing_public_key: %s\n",
543*8617a60dSAndroid Build Coastguard Worker filename);
544*8617a60dSAndroid Build Coastguard Worker goto cleanup_permutation;
545*8617a60dSAndroid Build Coastguard Worker }
546*8617a60dSAndroid Build Coastguard Worker
547*8617a60dSAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/key_%s.keyb",
548*8617a60dSAndroid Build Coastguard Worker keys_dir,
549*8617a60dSAndroid Build Coastguard Worker vb2_get_crypto_algorithm_file(data_key_algorithm));
550*8617a60dSAndroid Build Coastguard Worker data_public_key =
551*8617a60dSAndroid Build Coastguard Worker vb2_read_packed_keyb(filename, data_key_algorithm, 1);
552*8617a60dSAndroid Build Coastguard Worker if (!data_public_key) {
553*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Error reading data_public_key: %s\n",
554*8617a60dSAndroid Build Coastguard Worker filename);
555*8617a60dSAndroid Build Coastguard Worker goto cleanup_permutation;
556*8617a60dSAndroid Build Coastguard Worker }
557*8617a60dSAndroid Build Coastguard Worker
558*8617a60dSAndroid Build Coastguard Worker /* Unpack public key */
559*8617a60dSAndroid Build Coastguard Worker struct vb2_public_key signing_public_key2;
560*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS !=
561*8617a60dSAndroid Build Coastguard Worker vb2_unpack_key_buffer(&signing_public_key2,
562*8617a60dSAndroid Build Coastguard Worker (uint8_t *)signing_public_key,
563*8617a60dSAndroid Build Coastguard Worker signing_public_key->key_offset +
564*8617a60dSAndroid Build Coastguard Worker signing_public_key->key_size)) {
565*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Error unpacking signing_public_key: %s\n",
566*8617a60dSAndroid Build Coastguard Worker filename);
567*8617a60dSAndroid Build Coastguard Worker goto cleanup_permutation;
568*8617a60dSAndroid Build Coastguard Worker }
569*8617a60dSAndroid Build Coastguard Worker
570*8617a60dSAndroid Build Coastguard Worker test_check_keyblock(&signing_public_key2, signing_private_key,
571*8617a60dSAndroid Build Coastguard Worker data_public_key);
572*8617a60dSAndroid Build Coastguard Worker test_verify_keyblock(&signing_public_key2, signing_private_key,
573*8617a60dSAndroid Build Coastguard Worker data_public_key);
574*8617a60dSAndroid Build Coastguard Worker test_verify_fw_preamble(signing_public_key, signing_private_key,
575*8617a60dSAndroid Build Coastguard Worker data_public_key);
576*8617a60dSAndroid Build Coastguard Worker test_verify_kernel_preamble(signing_public_key, signing_private_key);
577*8617a60dSAndroid Build Coastguard Worker
578*8617a60dSAndroid Build Coastguard Worker retval = 0;
579*8617a60dSAndroid Build Coastguard Worker
580*8617a60dSAndroid Build Coastguard Worker cleanup_permutation:
581*8617a60dSAndroid Build Coastguard Worker if (signing_public_key)
582*8617a60dSAndroid Build Coastguard Worker free(signing_public_key);
583*8617a60dSAndroid Build Coastguard Worker if (signing_private_key)
584*8617a60dSAndroid Build Coastguard Worker free(signing_private_key);
585*8617a60dSAndroid Build Coastguard Worker if (data_public_key)
586*8617a60dSAndroid Build Coastguard Worker free(data_public_key);
587*8617a60dSAndroid Build Coastguard Worker
588*8617a60dSAndroid Build Coastguard Worker return retval;
589*8617a60dSAndroid Build Coastguard Worker }
590*8617a60dSAndroid Build Coastguard Worker
591*8617a60dSAndroid Build Coastguard Worker struct test_perm
592*8617a60dSAndroid Build Coastguard Worker {
593*8617a60dSAndroid Build Coastguard Worker int signing_algorithm;
594*8617a60dSAndroid Build Coastguard Worker int data_key_algorithm;
595*8617a60dSAndroid Build Coastguard Worker };
596*8617a60dSAndroid Build Coastguard Worker
597*8617a60dSAndroid Build Coastguard Worker /* Permutations of signing and data key algorithms in active use */
598*8617a60dSAndroid Build Coastguard Worker const struct test_perm test_perms[] = {
599*8617a60dSAndroid Build Coastguard Worker {VB2_ALG_RSA4096_SHA256, VB2_ALG_RSA2048_SHA256},
600*8617a60dSAndroid Build Coastguard Worker {VB2_ALG_RSA8192_SHA512, VB2_ALG_RSA2048_SHA256},
601*8617a60dSAndroid Build Coastguard Worker {VB2_ALG_RSA8192_SHA512, VB2_ALG_RSA4096_SHA256},
602*8617a60dSAndroid Build Coastguard Worker };
603*8617a60dSAndroid Build Coastguard Worker
main(int argc,char * argv[])604*8617a60dSAndroid Build Coastguard Worker int main(int argc, char *argv[])
605*8617a60dSAndroid Build Coastguard Worker {
606*8617a60dSAndroid Build Coastguard Worker if (argc == 2) {
607*8617a60dSAndroid Build Coastguard Worker /* Test only the algorithms we use */
608*8617a60dSAndroid Build Coastguard Worker int i;
609*8617a60dSAndroid Build Coastguard Worker
610*8617a60dSAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(test_perms); i++) {
611*8617a60dSAndroid Build Coastguard Worker if (test_permutation(test_perms[i].signing_algorithm,
612*8617a60dSAndroid Build Coastguard Worker test_perms[i].data_key_algorithm,
613*8617a60dSAndroid Build Coastguard Worker argv[1]))
614*8617a60dSAndroid Build Coastguard Worker return 1;
615*8617a60dSAndroid Build Coastguard Worker }
616*8617a60dSAndroid Build Coastguard Worker
617*8617a60dSAndroid Build Coastguard Worker } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
618*8617a60dSAndroid Build Coastguard Worker /* Test all the algorithms */
619*8617a60dSAndroid Build Coastguard Worker int sign_alg, data_alg;
620*8617a60dSAndroid Build Coastguard Worker
621*8617a60dSAndroid Build Coastguard Worker for (sign_alg = 0; sign_alg < VB2_ALG_COUNT; sign_alg++) {
622*8617a60dSAndroid Build Coastguard Worker for (data_alg = 0; data_alg < VB2_ALG_COUNT;
623*8617a60dSAndroid Build Coastguard Worker data_alg++) {
624*8617a60dSAndroid Build Coastguard Worker if (test_permutation(sign_alg, data_alg,
625*8617a60dSAndroid Build Coastguard Worker argv[1]))
626*8617a60dSAndroid Build Coastguard Worker return 1;
627*8617a60dSAndroid Build Coastguard Worker }
628*8617a60dSAndroid Build Coastguard Worker }
629*8617a60dSAndroid Build Coastguard Worker } else {
630*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
631*8617a60dSAndroid Build Coastguard Worker return -1;
632*8617a60dSAndroid Build Coastguard Worker }
633*8617a60dSAndroid Build Coastguard Worker
634*8617a60dSAndroid Build Coastguard Worker return gTestSuccess ? 0 : 255;
635*8617a60dSAndroid Build Coastguard Worker }
636