blob: e5538673b445cf1ec0ee08bbbb11f9b44b575f76 [file] [log] [blame]
Randall Spangler7141d732014-05-15 15:34:54 -07001/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for firmware image library.
6 */
7
Randall Spangler7141d732014-05-15 15:34:54 -07008#include <stdio.h>
Randall Spangler224f5ac2014-06-06 09:42:30 -07009
10#include "2sysincludes.h"
Randall Spangler224f5ac2014-06-06 09:42:30 -070011#include "2rsa.h"
Randall Spangler7141d732014-05-15 15:34:54 -070012
13#include "file_keys.h"
14#include "host_common.h"
15#include "host_key.h"
16#include "host_keyblock.h"
17#include "host_signature.h"
Randall Spangler6f1b82a2014-12-03 12:29:37 -080018#include "vb2_common.h"
Randall Spangler7141d732014-05-15 15:34:54 -070019#include "vboot_common.h"
20#include "test_common.h"
21
Randall Spangler939cc3a2016-06-21 15:23:32 -070022static void resign_keyblock(struct vb2_keyblock *h,
23 const struct vb2_private_key *key)
Randall Spangler7141d732014-05-15 15:34:54 -070024{
Randall Spangler939cc3a2016-06-21 15:23:32 -070025 struct vb2_signature *sig =
26 vb2_calculate_signature((const uint8_t *)h,
27 h->keyblock_signature.data_size, key);
Randall Spangler7141d732014-05-15 15:34:54 -070028
Randall Spangler939cc3a2016-06-21 15:23:32 -070029 vb2_copy_signature(&h->keyblock_signature, sig);
Randall Spangler7141d732014-05-15 15:34:54 -070030 free(sig);
31}
32
Randall Spangler939cc3a2016-06-21 15:23:32 -070033static void test_check_keyblock(const struct vb2_public_key *public_key,
34 const struct vb2_private_key *private_key,
35 const struct vb2_packed_key *data_key)
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070036{
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070037 struct vb2_keyblock *hdr;
38 struct vb2_keyblock *h;
39 struct vb2_signature *sig;
40 uint32_t hsize;
41
Randall Spangler939cc3a2016-06-21 15:23:32 -070042 hdr = vb2_create_keyblock(data_key, private_key, 0x1234);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070043 TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites");
44 if (!hdr)
45 return;
46 hsize = hdr->keyblock_size;
47 h = (struct vb2_keyblock *)malloc(hsize + 2048);
48 sig = &h->keyblock_signature;
49
Randall Spangler664096b2016-10-13 16:16:41 -070050 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070051 TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
52 "vb2_check_keyblock() ok");
53
Randall Spangler664096b2016-10-13 16:16:41 -070054 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070055 TEST_EQ(vb2_check_keyblock(h, hsize - 1, sig),
56 VB2_ERROR_KEYBLOCK_SIZE, "vb2_check_keyblock() size--");
57
58 /* Buffer is allowed to be bigger than keyblock */
Randall Spangler664096b2016-10-13 16:16:41 -070059 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070060 TEST_SUCC(vb2_check_keyblock(h, hsize + 1, sig),
61 "vb2_check_keyblock() size++");
62
Randall Spangler664096b2016-10-13 16:16:41 -070063 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070064 h->magic[0] &= 0x12;
65 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
66 VB2_ERROR_KEYBLOCK_MAGIC, "vb2_check_keyblock() magic");
67
68 /* Care about major version but not minor */
Randall Spangler664096b2016-10-13 16:16:41 -070069 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070070 h->header_version_major++;
71 resign_keyblock(h, private_key);
72 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
73 VB2_ERROR_KEYBLOCK_HEADER_VERSION,
74 "vb2_check_keyblock() major++");
75
Randall Spangler664096b2016-10-13 16:16:41 -070076 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070077 h->header_version_major--;
78 resign_keyblock(h, private_key);
79 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
80 VB2_ERROR_KEYBLOCK_HEADER_VERSION,
81 "vb2_check_keyblock() major--");
82
Randall Spangler664096b2016-10-13 16:16:41 -070083 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070084 h->header_version_minor++;
85 resign_keyblock(h, private_key);
86 TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
87 "vb2_check_keyblock() minor++");
88
Randall Spangler664096b2016-10-13 16:16:41 -070089 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070090 h->header_version_minor--;
91 resign_keyblock(h, private_key);
92 TEST_SUCC(vb2_check_keyblock(h, hsize, sig),
93 "vb2_check_keyblock() minor--");
94
95 /* Check signature */
Randall Spangler664096b2016-10-13 16:16:41 -070096 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -070097 h->keyblock_signature.sig_offset = hsize;
98 resign_keyblock(h, private_key);
99 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
100 VB2_ERROR_KEYBLOCK_SIG_OUTSIDE,
101 "vb2_check_keyblock() sig off end");
102
Randall Spangler664096b2016-10-13 16:16:41 -0700103 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -0700104 h->keyblock_signature.data_size = h->keyblock_size + 1;
105 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
106 VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH,
107 "vb2_check_keyblock() sig data past end of block");
108
109 /* Check that we signed header and data key */
Randall Spangler664096b2016-10-13 16:16:41 -0700110 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -0700111 h->keyblock_signature.data_size = 4;
112 h->data_key.key_offset = 0;
113 h->data_key.key_size = 0;
114 resign_keyblock(h, private_key);
115 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
116 VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE,
117 "vb2_check_keyblock() didn't sign header");
118
Randall Spangler664096b2016-10-13 16:16:41 -0700119 memcpy(h, hdr, hsize);
Randall Spanglerb87d1ec2015-05-19 12:45:20 -0700120 h->data_key.key_offset = hsize;
121 resign_keyblock(h, private_key);
122 TEST_EQ(vb2_check_keyblock(h, hsize, sig),
123 VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE,
124 "vb2_check_keyblock() data key off end");
125
126 /* Corner cases for error checking */
127 TEST_EQ(vb2_check_keyblock(NULL, 4, sig),
128 VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER,
129 "vb2_check_keyblock size too small");
130
131 /*
132 * TODO: verify parser can support a bigger header (i.e., one where
133 * data_key.key_offset is bigger than expected).
134 */
135
136 free(h);
137 free(hdr);
138}
139
Randall Spangler939cc3a2016-06-21 15:23:32 -0700140static void test_verify_keyblock(const struct vb2_public_key *public_key,
141 const struct vb2_private_key *private_key,
142 const struct vb2_packed_key *data_key)
Randall Spangler7141d732014-05-15 15:34:54 -0700143{
Bill Richardson73e5eb32015-01-26 12:18:25 -0800144 uint8_t workbuf[VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES]
145 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
Randall Spangler7141d732014-05-15 15:34:54 -0700146 struct vb2_workbuf wb;
Randall Spangler7141d732014-05-15 15:34:54 -0700147 struct vb2_keyblock *hdr;
148 struct vb2_keyblock *h;
149 uint32_t hsize;
150
151 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
152
Randall Spangler939cc3a2016-06-21 15:23:32 -0700153 hdr = vb2_create_keyblock(data_key, private_key, 0x1234);
Randall Spangler7141d732014-05-15 15:34:54 -0700154 TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites");
155 if (!hdr)
156 return;
157 hsize = hdr->keyblock_size;
158 h = (struct vb2_keyblock *)malloc(hsize + 2048);
159
Randall Spangler664096b2016-10-13 16:16:41 -0700160 memcpy(h, hdr, hsize);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700161 TEST_SUCC(vb2_verify_keyblock(h, hsize, public_key, &wb),
Randall Spangler224f5ac2014-06-06 09:42:30 -0700162 "vb2_verify_keyblock() ok using key");
Randall Spangler7141d732014-05-15 15:34:54 -0700163
Randall Spanglerb87d1ec2015-05-19 12:45:20 -0700164 /* Failures in keyblock check also cause verify to fail */
Randall Spangler664096b2016-10-13 16:16:41 -0700165 memcpy(h, hdr, hsize);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700166 TEST_EQ(vb2_verify_keyblock(h, hsize - 1, public_key, &wb),
Randall Spanglerb87d1ec2015-05-19 12:45:20 -0700167 VB2_ERROR_KEYBLOCK_SIZE, "vb2_verify_keyblock() check");
Randall Spangler7141d732014-05-15 15:34:54 -0700168
169 /* Check signature */
Randall Spangler664096b2016-10-13 16:16:41 -0700170 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700171 h->keyblock_signature.sig_size--;
172 resign_keyblock(h, private_key);
Randall Spangler939cc3a2016-06-21 15:23:32 -0700173 TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb),
Randall Spangler224f5ac2014-06-06 09:42:30 -0700174 VB2_ERROR_KEYBLOCK_SIG_INVALID,
175 "vb2_verify_keyblock() sig too small");
Randall Spangler7141d732014-05-15 15:34:54 -0700176
Randall Spangler664096b2016-10-13 16:16:41 -0700177 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700178 ((uint8_t *)vb2_packed_key_data(&h->data_key))[0] ^= 0x34;
Randall Spangler939cc3a2016-06-21 15:23:32 -0700179 TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb),
Randall Spangler224f5ac2014-06-06 09:42:30 -0700180 VB2_ERROR_KEYBLOCK_SIG_INVALID,
181 "vb2_verify_keyblock() sig mismatch");
Randall Spangler7141d732014-05-15 15:34:54 -0700182
Randall Spangler7141d732014-05-15 15:34:54 -0700183 /*
184 * TODO: verify parser can support a bigger header (i.e., one where
185 * data_key.key_offset is bigger than expected).
186 */
187
188 free(h);
189 free(hdr);
190}
191
192static void resign_fw_preamble(struct vb2_fw_preamble *h,
Randall Spangler814aaf02016-06-17 10:48:16 -0700193 struct vb2_private_key *key)
Randall Spangler7141d732014-05-15 15:34:54 -0700194{
Randall Spangler814aaf02016-06-17 10:48:16 -0700195 struct vb2_signature *sig = vb2_calculate_signature(
Randall Spangler7141d732014-05-15 15:34:54 -0700196 (const uint8_t *)h, h->preamble_signature.data_size, key);
197
Randall Spangler814aaf02016-06-17 10:48:16 -0700198 vb2_copy_signature(&h->preamble_signature, sig);
Randall Spangler7141d732014-05-15 15:34:54 -0700199 free(sig);
200}
201
Randall Spanglerf7559e42016-06-23 13:45:59 -0700202static void test_verify_fw_preamble(struct vb2_packed_key *public_key,
Randall Spangler814aaf02016-06-17 10:48:16 -0700203 struct vb2_private_key *private_key,
204 struct vb2_packed_key *kernel_subkey)
Randall Spangler7141d732014-05-15 15:34:54 -0700205{
206 struct vb2_fw_preamble *hdr;
207 struct vb2_fw_preamble *h;
208 struct vb2_public_key rsa;
Bill Richardson73e5eb32015-01-26 12:18:25 -0800209 uint8_t workbuf[VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES]
210 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
Randall Spangler7141d732014-05-15 15:34:54 -0700211 struct vb2_workbuf wb;
212 uint32_t hsize;
213
214 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
215
216 /* Create a dummy signature */
Randall Spangler814aaf02016-06-17 10:48:16 -0700217 struct vb2_signature *body_sig = vb2_alloc_signature(56, 78);
Randall Spangler7141d732014-05-15 15:34:54 -0700218
Randall Spangler224f5ac2014-06-06 09:42:30 -0700219 TEST_SUCC(vb2_unpack_key(&rsa, (uint8_t *)public_key,
220 public_key->key_offset + public_key->key_size),
221 "vb2_verify_fw_preamble() prereq key");
Randall Spangler7141d732014-05-15 15:34:54 -0700222
Randall Spangler814aaf02016-06-17 10:48:16 -0700223 hdr = vb2_create_fw_preamble(0x1234, kernel_subkey, body_sig,
224 private_key, 0x5678);
Randall Spangler7141d732014-05-15 15:34:54 -0700225 TEST_PTR_NEQ(hdr, NULL,
Randall Spangler814aaf02016-06-17 10:48:16 -0700226 "vb2_verify_fw_preamble() prereq test preamble");
Randall Spangler770202f2016-09-28 11:54:20 -0700227 if (!hdr) {
228 free(body_sig);
Randall Spangler7141d732014-05-15 15:34:54 -0700229 return;
Randall Spangler770202f2016-09-28 11:54:20 -0700230 }
231
Randall Spangler7141d732014-05-15 15:34:54 -0700232 hsize = (uint32_t) hdr->preamble_size;
233 h = (struct vb2_fw_preamble *)malloc(hsize + 16384);
234
Randall Spangler664096b2016-10-13 16:16:41 -0700235 memcpy(h, hdr, hsize);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700236 TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
237 "vb2_verify_fw_preamble() ok using key");
Randall Spangler7141d732014-05-15 15:34:54 -0700238
Randall Spangler664096b2016-10-13 16:16:41 -0700239 memcpy(h, hdr, hsize);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700240 TEST_EQ(vb2_verify_fw_preamble(h, 4, &rsa, &wb),
241 VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
242 "vb2_verify_fw_preamble() size tiny");
Randall Spangler7141d732014-05-15 15:34:54 -0700243
Randall Spangler664096b2016-10-13 16:16:41 -0700244 memcpy(h, hdr, hsize);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700245 TEST_EQ(vb2_verify_fw_preamble(h, hsize - 1, &rsa, &wb),
246 VB2_ERROR_PREAMBLE_SIZE,
247 "vb2_verify_fw_preamble() size--");
Randall Spangler7141d732014-05-15 15:34:54 -0700248
Randall Spangler224f5ac2014-06-06 09:42:30 -0700249 /* Buffer is allowed to be bigger than preamble */
Randall Spangler664096b2016-10-13 16:16:41 -0700250 memcpy(h, hdr, hsize);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700251 TEST_SUCC(vb2_verify_fw_preamble(h, hsize + 1, &rsa, &wb),
252 "vb2_verify_fw_preamble() size++");
Randall Spangler7141d732014-05-15 15:34:54 -0700253
254 /* Care about major version but not minor */
Randall Spangler664096b2016-10-13 16:16:41 -0700255 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700256 h->header_version_major++;
257 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700258 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
259 VB2_ERROR_PREAMBLE_HEADER_VERSION
260 , "vb2_verify_fw_preamble() major++");
Randall Spangler7141d732014-05-15 15:34:54 -0700261
Randall Spangler664096b2016-10-13 16:16:41 -0700262 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700263 h->header_version_major--;
264 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700265 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
266 VB2_ERROR_PREAMBLE_HEADER_VERSION,
267 "vb2_verify_fw_preamble() major--");
Randall Spangler7141d732014-05-15 15:34:54 -0700268
Randall Spangler664096b2016-10-13 16:16:41 -0700269 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700270 h->header_version_minor++;
271 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700272 TEST_SUCC(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
273 "vb2_verify_fw_preamble() minor++");
Randall Spangler7141d732014-05-15 15:34:54 -0700274
Randall Spangler664096b2016-10-13 16:16:41 -0700275 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700276 h->header_version_minor--;
277 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700278 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
279 VB2_ERROR_PREAMBLE_HEADER_OLD,
280 "vb2_verify_fw_preamble() 2.0 not supported");
Randall Spangler7141d732014-05-15 15:34:54 -0700281
282 /* Check signature */
Randall Spangler664096b2016-10-13 16:16:41 -0700283 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700284 h->preamble_signature.sig_offset = hsize;
285 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700286 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
287 VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
288 "vb2_verify_fw_preamble() sig off end");
Randall Spangler7141d732014-05-15 15:34:54 -0700289
Randall Spangler664096b2016-10-13 16:16:41 -0700290 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700291 h->preamble_signature.sig_size--;
292 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700293 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
294 VB2_ERROR_PREAMBLE_SIG_INVALID,
295 "vb2_verify_fw_preamble() sig too small");
Randall Spangler7141d732014-05-15 15:34:54 -0700296
Randall Spangler664096b2016-10-13 16:16:41 -0700297 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700298 ((uint8_t *)vb2_packed_key_data(&h->kernel_subkey))[0] ^= 0x34;
Randall Spangler224f5ac2014-06-06 09:42:30 -0700299 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
300 VB2_ERROR_PREAMBLE_SIG_INVALID,
301 "vb2_verify_fw_preamble() sig mismatch");
Randall Spangler7141d732014-05-15 15:34:54 -0700302
303 /* Check that we signed header, kernel subkey, and body sig */
Randall Spangler664096b2016-10-13 16:16:41 -0700304 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700305 h->preamble_signature.data_size = 4;
306 h->kernel_subkey.key_offset = 0;
307 h->kernel_subkey.key_size = 0;
308 h->body_signature.sig_offset = 0;
309 h->body_signature.sig_size = 0;
310 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700311 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
312 VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
313 "vb2_verify_fw_preamble() didn't sign header");
Randall Spangler7141d732014-05-15 15:34:54 -0700314
Randall Spangler664096b2016-10-13 16:16:41 -0700315 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700316 h->kernel_subkey.key_offset = hsize;
317 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700318 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
319 VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE,
320 "vb2_verify_fw_preamble() kernel subkey off end");
Randall Spangler7141d732014-05-15 15:34:54 -0700321
Randall Spangler664096b2016-10-13 16:16:41 -0700322 memcpy(h, hdr, hsize);
Randall Spangler7141d732014-05-15 15:34:54 -0700323 h->body_signature.sig_offset = hsize;
324 resign_fw_preamble(h, private_key);
Randall Spangler224f5ac2014-06-06 09:42:30 -0700325 TEST_EQ(vb2_verify_fw_preamble(h, hsize, &rsa, &wb),
326 VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
327 "vb2_verify_fw_preamble() body sig off end");
Randall Spangler7141d732014-05-15 15:34:54 -0700328
329 /* TODO: verify with extra padding at end of header. */
330
331 free(h);
332 free(hdr);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700333 free(body_sig);
Randall Spangler7141d732014-05-15 15:34:54 -0700334}
335
Randall Spangler2d25e832015-05-12 16:39:01 -0700336static void resign_kernel_preamble(struct vb2_kernel_preamble *h,
Randall Spanglerd46461c2016-06-22 16:46:23 -0700337 const struct vb2_private_key *key)
Randall Spangler2d25e832015-05-12 16:39:01 -0700338{
Randall Spanglerd46461c2016-06-22 16:46:23 -0700339 struct vb2_signature *sig = vb2_calculate_signature(
Randall Spangler2d25e832015-05-12 16:39:01 -0700340 (const uint8_t *)h, h->preamble_signature.data_size, key);
341
Randall Spanglerd46461c2016-06-22 16:46:23 -0700342 vb2_copy_signature(&h->preamble_signature, sig);
Randall Spangler2d25e832015-05-12 16:39:01 -0700343 free(sig);
344}
345
Randall Spanglerd46461c2016-06-22 16:46:23 -0700346static void test_verify_kernel_preamble(
Randall Spanglerf7559e42016-06-23 13:45:59 -0700347 const struct vb2_packed_key *public_key,
Randall Spanglerd46461c2016-06-22 16:46:23 -0700348 const struct vb2_private_key *private_key)
Randall Spangler2d25e832015-05-12 16:39:01 -0700349{
Randall Spangler2d25e832015-05-12 16:39:01 -0700350 struct vb2_public_key rsa;
351 // TODO: how many workbuf bytes?
352 uint8_t workbuf[VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES]
353 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
354 struct vb2_workbuf wb;
355 uint32_t hsize;
356
357 vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
358
359 /* Create a dummy signature */
Randall Spangler814aaf02016-06-17 10:48:16 -0700360 struct vb2_signature *body_sig = vb2_alloc_signature(56, 0x214000);
Randall Spangler2d25e832015-05-12 16:39:01 -0700361
362 TEST_SUCC(vb2_unpack_key(&rsa, (uint8_t *)public_key,
363 public_key->key_offset + public_key->key_size),
364 "vb2_verify_kernel_preamble() prereq key");
365
Randall Spanglera62ffa82016-06-30 11:24:24 -0700366 struct vb2_kernel_preamble *hdr =
367 vb2_create_kernel_preamble(0x1234, 0x100000, 0x300000, 0x4000,
368 body_sig, 0x304000, 0x10000, 0, 0,
369 private_key);
Randall Spangler2d25e832015-05-12 16:39:01 -0700370 TEST_PTR_NEQ(hdr, NULL,
371 "vb2_verify_kernel_preamble() prereq test preamble");
Randall Spangler770202f2016-09-28 11:54:20 -0700372 if (!hdr) {
373 free(body_sig);
Randall Spangler2d25e832015-05-12 16:39:01 -0700374 return;
Randall Spangler770202f2016-09-28 11:54:20 -0700375 }
376
Randall Spangler2d25e832015-05-12 16:39:01 -0700377 hsize = (uint32_t) hdr->preamble_size;
Randall Spanglera62ffa82016-06-30 11:24:24 -0700378 struct vb2_kernel_preamble *h =
379 (struct vb2_kernel_preamble *)malloc(hsize + 16384);
Randall Spangler2d25e832015-05-12 16:39:01 -0700380
Randall Spangler664096b2016-10-13 16:16:41 -0700381 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700382 TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
383 "vb2_verify_kernel_preamble() ok using key");
384
Randall Spangler664096b2016-10-13 16:16:41 -0700385 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700386 TEST_EQ(vb2_verify_kernel_preamble(h, 4, &rsa, &wb),
387 VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER,
388 "vb2_verify_kernel_preamble() size tiny");
389
Randall Spangler664096b2016-10-13 16:16:41 -0700390 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700391 TEST_EQ(vb2_verify_kernel_preamble(h, hsize - 1, &rsa, &wb),
392 VB2_ERROR_PREAMBLE_SIZE,
393 "vb2_verify_kernel_preamble() size--");
394
395 /* Buffer is allowed to be bigger than preamble */
Randall Spangler664096b2016-10-13 16:16:41 -0700396 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700397 TEST_SUCC(vb2_verify_kernel_preamble(h, hsize + 1, &rsa, &wb),
398 "vb2_verify_kernel_preamble() size++");
399
400 /* Care about major version but not minor */
Randall Spangler664096b2016-10-13 16:16:41 -0700401 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700402 h->header_version_major++;
403 resign_kernel_preamble(h, private_key);
404 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
405 VB2_ERROR_PREAMBLE_HEADER_VERSION
406 , "vb2_verify_kernel_preamble() major++");
407
Randall Spangler664096b2016-10-13 16:16:41 -0700408 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700409 h->header_version_major--;
410 resign_kernel_preamble(h, private_key);
411 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
412 VB2_ERROR_PREAMBLE_HEADER_VERSION,
413 "vb2_verify_kernel_preamble() major--");
414
Randall Spangler664096b2016-10-13 16:16:41 -0700415 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700416 h->header_version_minor++;
417 resign_kernel_preamble(h, private_key);
418 TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
419 "vb2_verify_kernel_preamble() minor++");
420
Randall Spangler2d25e832015-05-12 16:39:01 -0700421 /* Check signature */
Randall Spangler664096b2016-10-13 16:16:41 -0700422 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700423 h->preamble_signature.sig_offset = hsize;
424 resign_kernel_preamble(h, private_key);
425 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
426 VB2_ERROR_PREAMBLE_SIG_OUTSIDE,
427 "vb2_verify_kernel_preamble() sig off end");
428
Randall Spangler664096b2016-10-13 16:16:41 -0700429 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700430 h->preamble_signature.sig_size--;
431 resign_kernel_preamble(h, private_key);
432 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
433 VB2_ERROR_PREAMBLE_SIG_INVALID,
434 "vb2_verify_kernel_preamble() sig too small");
435
Randall Spangler664096b2016-10-13 16:16:41 -0700436 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700437 h->flags++;
438 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
439 VB2_ERROR_PREAMBLE_SIG_INVALID,
440 "vb2_verify_kernel_preamble() sig mismatch");
441
442 /* Check that we signed header and body sig */
Randall Spangler664096b2016-10-13 16:16:41 -0700443 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700444 h->preamble_signature.data_size = 4;
445 h->body_signature.sig_offset = 0;
446 h->body_signature.sig_size = 0;
447 resign_kernel_preamble(h, private_key);
448 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
449 VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE,
450 "vb2_verify_kernel_preamble() didn't sign header");
451
Randall Spangler664096b2016-10-13 16:16:41 -0700452 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700453 h->body_signature.sig_offset = hsize;
454 resign_kernel_preamble(h, private_key);
455 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
456 VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE,
457 "vb2_verify_kernel_preamble() body sig off end");
458
459 /* Check bootloader inside signed body */
Randall Spangler664096b2016-10-13 16:16:41 -0700460 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700461 h->bootloader_address = h->body_load_address - 1;
462 resign_kernel_preamble(h, private_key);
463 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
464 VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE,
465 "vb2_verify_kernel_preamble() bootloader before body");
466
Randall Spangler664096b2016-10-13 16:16:41 -0700467 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700468 h->bootloader_address = h->body_load_address +
469 h->body_signature.data_size + 1;
470 resign_kernel_preamble(h, private_key);
471 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
472 VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE,
473 "vb2_verify_kernel_preamble() bootloader off end of body");
474
Randall Spangler664096b2016-10-13 16:16:41 -0700475 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700476 h->bootloader_address = h->body_load_address +
477 h->body_signature.data_size + 1;
478 h->bootloader_size = 0;
479 resign_kernel_preamble(h, private_key);
480 TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
481 "vb2_verify_kernel_preamble() no bootloader");
482
483 /* Check vmlinuz inside signed body */
Randall Spangler664096b2016-10-13 16:16:41 -0700484 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700485 h->vmlinuz_header_address = h->body_load_address - 1;
486 resign_kernel_preamble(h, private_key);
487 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
488 VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE,
489 "vb2_verify_kernel_preamble() vmlinuz_header before body");
490
Randall Spangler664096b2016-10-13 16:16:41 -0700491 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700492 h->vmlinuz_header_address = h->body_load_address +
493 h->body_signature.data_size + 1;
494 resign_kernel_preamble(h, private_key);
495 TEST_EQ(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
496 VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE,
497 "vb2_verify_kernel_preamble() vmlinuz_header off end of body");
498
Randall Spangler664096b2016-10-13 16:16:41 -0700499 memcpy(h, hdr, hsize);
Randall Spangler2d25e832015-05-12 16:39:01 -0700500 h->vmlinuz_header_address = h->body_load_address +
501 h->body_signature.data_size + 1;
502 h->vmlinuz_header_size = 0;
503 resign_kernel_preamble(h, private_key);
504 TEST_SUCC(vb2_verify_kernel_preamble(h, hsize, &rsa, &wb),
505 "vb2_verify_kernel_preamble() no vmlinuz_header");
506
507 /* TODO: verify with extra padding at end of header. */
508
509 free(h);
510 free(hdr);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700511 free(body_sig);
Randall Spangler2d25e832015-05-12 16:39:01 -0700512}
513
Randall Spangler7141d732014-05-15 15:34:54 -0700514int test_permutation(int signing_key_algorithm, int data_key_algorithm,
515 const char *keys_dir)
516{
517 char filename[1024];
Randall Spangler46a382d2016-10-18 12:00:07 -0700518 int signing_rsa_len = 8 * vb2_rsa_sig_size(
519 vb2_crypto_to_signature(signing_key_algorithm));
520 int data_rsa_len = 8 * vb2_rsa_sig_size(
521 vb2_crypto_to_signature(data_key_algorithm));
Randall Spanglerf87aa722016-09-09 10:49:37 -0700522 int retval = 1;
523
524 struct vb2_private_key *signing_private_key = NULL;
525 struct vb2_packed_key *signing_public_key = NULL;
526 struct vb2_packed_key *data_public_key = NULL;
Randall Spangler7141d732014-05-15 15:34:54 -0700527
Randall Spangler7141d732014-05-15 15:34:54 -0700528 printf("***Testing signing algorithm: %s\n",
Randall Spangler46a382d2016-10-18 12:00:07 -0700529 vb2_get_crypto_algorithm_name(signing_key_algorithm));
Randall Spangler7141d732014-05-15 15:34:54 -0700530 printf("***With data key algorithm: %s\n",
Randall Spangler46a382d2016-10-18 12:00:07 -0700531 vb2_get_crypto_algorithm_name(data_key_algorithm));
Randall Spangler7141d732014-05-15 15:34:54 -0700532
Randall Spanglerf87aa722016-09-09 10:49:37 -0700533 snprintf(filename, sizeof(filename),
534 "%s/key_rsa%d.pem", keys_dir, signing_rsa_len);
535 signing_private_key =
Randall Spangler814aaf02016-06-17 10:48:16 -0700536 vb2_read_private_key_pem(filename, signing_key_algorithm);
Randall Spanglerd46461c2016-06-22 16:46:23 -0700537 if (!signing_private_key) {
Randall Spangler814aaf02016-06-17 10:48:16 -0700538 fprintf(stderr, "Error reading signing_private_key: %s\n",
539 filename);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700540 goto cleanup_permutation;
Randall Spangler814aaf02016-06-17 10:48:16 -0700541 }
542
Randall Spanglerf87aa722016-09-09 10:49:37 -0700543 snprintf(filename, sizeof(filename),
544 "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len);
545 signing_public_key =
Randall Spanglerf7559e42016-06-23 13:45:59 -0700546 vb2_read_packed_keyb(filename, signing_key_algorithm, 1);
Randall Spangler7141d732014-05-15 15:34:54 -0700547 if (!signing_public_key) {
548 fprintf(stderr, "Error reading signing_public_key: %s\n",
549 filename);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700550 goto cleanup_permutation;
Randall Spangler7141d732014-05-15 15:34:54 -0700551 }
552
Randall Spanglerf87aa722016-09-09 10:49:37 -0700553 snprintf(filename, sizeof(filename),
554 "%s/key_rsa%d.keyb", keys_dir, data_rsa_len);
555 data_public_key =
Randall Spanglerf7559e42016-06-23 13:45:59 -0700556 vb2_read_packed_keyb(filename, data_key_algorithm, 1);
Randall Spangler7141d732014-05-15 15:34:54 -0700557 if (!data_public_key) {
558 fprintf(stderr, "Error reading data_public_key: %s\n",
559 filename);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700560 goto cleanup_permutation;
Randall Spangler7141d732014-05-15 15:34:54 -0700561 }
562
Randall Spangler939cc3a2016-06-21 15:23:32 -0700563 /* Unpack public key */
564 struct vb2_public_key signing_public_key2;
565 if (VB2_SUCCESS !=
566 vb2_unpack_key(&signing_public_key2,
567 (uint8_t *)signing_public_key,
568 signing_public_key->key_offset +
569 signing_public_key->key_size)) {
570 fprintf(stderr, "Error unpacking signing_public_key: %s\n",
571 filename);
Randall Spanglerf87aa722016-09-09 10:49:37 -0700572 goto cleanup_permutation;
Randall Spangler939cc3a2016-06-21 15:23:32 -0700573 }
574
Randall Spanglerd46461c2016-06-22 16:46:23 -0700575 test_check_keyblock(&signing_public_key2, signing_private_key,
Randall Spanglerf7559e42016-06-23 13:45:59 -0700576 data_public_key);
Randall Spanglerd46461c2016-06-22 16:46:23 -0700577 test_verify_keyblock(&signing_public_key2, signing_private_key,
Randall Spanglerf7559e42016-06-23 13:45:59 -0700578 data_public_key);
Randall Spanglerd46461c2016-06-22 16:46:23 -0700579 test_verify_fw_preamble(signing_public_key, signing_private_key,
Randall Spanglerf7559e42016-06-23 13:45:59 -0700580 data_public_key);
Randall Spangler2d25e832015-05-12 16:39:01 -0700581 test_verify_kernel_preamble(signing_public_key, signing_private_key);
Randall Spangler7141d732014-05-15 15:34:54 -0700582
Randall Spanglerf87aa722016-09-09 10:49:37 -0700583 retval = 0;
584
585cleanup_permutation:
Randall Spangler7141d732014-05-15 15:34:54 -0700586 if (signing_public_key)
587 free(signing_public_key);
588 if (signing_private_key)
589 free(signing_private_key);
Randall Spangler7141d732014-05-15 15:34:54 -0700590 if (data_public_key)
591 free(data_public_key);
592
Randall Spanglerf87aa722016-09-09 10:49:37 -0700593 return retval;
Randall Spangler7141d732014-05-15 15:34:54 -0700594}
595
596struct test_perm
597{
598 int signing_algorithm;
599 int data_key_algorithm;
600};
601
602/* Permutations of signing and data key algorithms in active use */
603const struct test_perm test_perms[] = {
604 {VB2_ALG_RSA4096_SHA256, VB2_ALG_RSA2048_SHA256},
605 {VB2_ALG_RSA8192_SHA512, VB2_ALG_RSA2048_SHA256},
606 {VB2_ALG_RSA8192_SHA512, VB2_ALG_RSA4096_SHA256},
607};
608
609int main(int argc, char *argv[])
610{
611 if (argc == 2) {
612 /* Test only the algorithms we use */
613 int i;
614
615 for (i = 0; i < ARRAY_SIZE(test_perms); i++) {
616 if (test_permutation(test_perms[i].signing_algorithm,
617 test_perms[i].data_key_algorithm,
618 argv[1]))
619 return 1;
620 }
621
622 } else if (argc == 3 && !strcasecmp(argv[2], "--all")) {
623 /* Test all the algorithms */
624 int sign_alg, data_alg;
625
626 for (sign_alg = 0; sign_alg < VB2_ALG_COUNT; sign_alg++) {
627 for (data_alg = 0; data_alg < VB2_ALG_COUNT;
628 data_alg++) {
629 if (test_permutation(sign_alg, data_alg,
630 argv[1]))
631 return 1;
632 }
633 }
634 } else {
635 fprintf(stderr, "Usage: %s <keys_dir> [--all]", argv[0]);
636 return -1;
637 }
638
639 return gTestSuccess ? 0 : 255;
640}