• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2013 The ChromiumOS Authors
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 vboot_kernel.c
6  */
7 
8 #include "2api.h"
9 #include "2common.h"
10 #include "2misc.h"
11 #include "2nvstorage.h"
12 #include "2secdata.h"
13 #include "2secdata_struct.h"
14 #include "cgptlib.h"
15 #include "cgptlib_internal.h"
16 #include "common/boot_mode.h"
17 #include "common/tests.h"
18 #include "gpt.h"
19 #include "vboot_api.h"
20 
21 /* Mock kernel partition */
22 struct mock_part {
23 	GptEntry e;
24 	struct vb2_keyblock kbh;
25 };
26 
27 /* Partition list; ends with a 0-size partition. */
28 #define MOCK_PART_COUNT 8
29 static struct mock_part mock_parts[MOCK_PART_COUNT];
30 static int mock_part_next;
31 
32 /* Mock data */
33 static uint8_t kernel_buffer[80000];
34 static int disk_read_to_fail;
35 static int gpt_init_fail;
36 static int keyblock_verify_fail;  /* 0=ok, 1=sig, 2=hash */
37 static int preamble_verify_fail;
38 static int verify_data_fail;
39 static int unpack_key_fail;
40 static int gpt_flag_external;
41 
42 static struct vb2_gbb_header gbb;
43 static struct vb2_kernel_params lkp;
44 static struct vb2_disk_info disk_info;
45 static struct vb2_keyblock cur_kbh;
46 static struct vb2_kernel_preamble kph;
47 static struct vb2_secdata_fwmp *fwmp;
48 static uint8_t mock_digest[VB2_SHA256_DIGEST_SIZE] = {12, 34, 56, 78};
49 static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
50 	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
51 static struct vb2_context *ctx;
52 static struct vb2_shared_data *sd;
53 static struct vb2_packed_key mock_key;
54 
55 /**
56  * Reset mock data (for use before each test)
57  */
ResetMocks(void)58 static void ResetMocks(void)
59 {
60 	disk_read_to_fail = -1;
61 
62 	gpt_init_fail = 0;
63 	keyblock_verify_fail = 0;
64 	preamble_verify_fail = 0;
65 	verify_data_fail = 0;
66 	unpack_key_fail = 0;
67 
68 	gpt_flag_external = 0;
69 
70 	memset(&gbb, 0, sizeof(gbb));
71 	gbb.major_version = VB2_GBB_MAJOR_VER;
72 	gbb.minor_version = VB2_GBB_MINOR_VER;
73 	gbb.flags = 0;
74 
75 	memset(&lkp, 0, sizeof(lkp));
76 	lkp.kernel_buffer = kernel_buffer;
77 	lkp.kernel_buffer_size = sizeof(kernel_buffer);
78 
79 	memset(&disk_info, 0, sizeof(disk_info));
80 	disk_info.bytes_per_lba = 512;
81 	disk_info.streaming_lba_count = 1024;
82 	disk_info.lba_count = 1024;
83 	disk_info.handle = (vb2ex_disk_handle_t)1;
84 
85 	memset(mock_parts, 0, sizeof(mock_parts));
86 	mock_parts[0].e.starting_lba = 100;
87 	mock_parts[0].e.ending_lba = 249; /* 75 KB */
88 	mock_parts[0].kbh = (struct vb2_keyblock){
89 		.data_key.key_version = 2,
90 		.keyblock_flags = -1,
91 		.keyblock_size = sizeof(mock_parts[0].kbh),
92 	};
93 	mock_part_next = 0;
94 
95 	memset(&cur_kbh, 0, sizeof(cur_kbh));
96 
97 	memset(&kph, 0, sizeof(kph));
98 	kph.kernel_version = 1;
99 	kph.preamble_size = 4096 - mock_parts[0].kbh.keyblock_size;
100 	kph.body_signature.data_size = 70144;
101 	kph.bootloader_address = 0xbeadd008;
102 	kph.bootloader_size = 0x1234;
103 
104 	memset(&mock_key, 0, sizeof(mock_key));
105 
106 	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
107 		  "vb2api_init failed");
108 	vb2_nv_init(ctx);
109 
110 	sd = vb2_get_sd(ctx);
111 	sd->kernel_version_secdata = 0x20001;
112 
113 	/* CRC will be invalid after here, but nobody's checking */
114 	sd->status |= VB2_SD_STATUS_SECDATA_FWMP_INIT;
115 	fwmp = (struct vb2_secdata_fwmp *)ctx->secdata_fwmp;
116 	memcpy(&fwmp->dev_key_hash, mock_digest, sizeof(fwmp->dev_key_hash));
117 
118 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_NORMAL);
119 
120 	// TODO: more workbuf fields - flags, secdata_firmware
121 
122 	vb2api_secdata_kernel_create(ctx);
123 	vb2_secdata_kernel_init(ctx);
124 	vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS,
125 			VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED);
126 }
127 
128 /* Mocks */
vb2_get_gbb(struct vb2_context * c)129 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
130 {
131 	return &gbb;
132 }
133 
vb2ex_read_resource(struct vb2_context * c,enum vb2_resource_index index,uint32_t offset,void * buf,uint32_t size)134 vb2_error_t vb2ex_read_resource(struct vb2_context *c,
135 				enum vb2_resource_index index, uint32_t offset,
136 				void *buf, uint32_t size)
137 {
138 	memset(buf, 0, size);
139 	return VB2_SUCCESS;
140 }
141 
vb2_gbb_read_root_key(struct vb2_context * c,struct vb2_packed_key ** keyp,uint32_t * size,struct vb2_workbuf * wb)142 vb2_error_t vb2_gbb_read_root_key(struct vb2_context *c,
143 				  struct vb2_packed_key **keyp, uint32_t *size,
144 				  struct vb2_workbuf *wb)
145 {
146 	*keyp = &mock_key;
147 	return VB2_SUCCESS;
148 }
149 
vb2_gbb_read_recovery_key(struct vb2_context * c,struct vb2_packed_key ** keyp,uint32_t * size,struct vb2_workbuf * wb)150 vb2_error_t vb2_gbb_read_recovery_key(struct vb2_context *c,
151 				      struct vb2_packed_key **keyp,
152 				      uint32_t *size, struct vb2_workbuf *wb)
153 {
154 	*keyp = &mock_key;
155 	return VB2_SUCCESS;
156 }
157 
VbExDiskRead(vb2ex_disk_handle_t h,uint64_t lba_start,uint64_t lba_count,void * buffer)158 vb2_error_t VbExDiskRead(vb2ex_disk_handle_t h, uint64_t lba_start,
159 			 uint64_t lba_count, void *buffer)
160 {
161 	if ((int)lba_start == disk_read_to_fail)
162 		return VB2_ERROR_MOCK;
163 
164 	return VB2_SUCCESS;
165 }
166 
AllocAndReadGptData(vb2ex_disk_handle_t disk_handle,GptData * gptdata)167 int AllocAndReadGptData(vb2ex_disk_handle_t disk_handle, GptData *gptdata)
168 {
169 	return GPT_SUCCESS;
170 }
171 
GptInit(GptData * gpt)172 int GptInit(GptData *gpt)
173 {
174 	return gpt_init_fail;
175 }
176 
GptGetEntrySizeLba(const GptEntry * e)177 uint64_t GptGetEntrySizeLba(const GptEntry *e)
178 {
179 	return (e->ending_lba - e->starting_lba + 1);
180 }
181 
GptNextKernelEntry(GptData * gpt)182 GptEntry *GptNextKernelEntry(GptData *gpt)
183 {
184 	struct mock_part *p = mock_parts + mock_part_next;
185 
186 	if (!p->e.ending_lba)
187 		return NULL;
188 
189 	if (gpt->flags & GPT_FLAG_EXTERNAL)
190 		gpt_flag_external++;
191 
192 	memcpy(&cur_kbh, &mock_parts[mock_part_next].kbh, sizeof(cur_kbh));
193 
194 	gpt->current_kernel = mock_part_next;
195 	mock_part_next++;
196 	return &p->e;
197 }
198 
GptUpdateKernelEntry(GptData * gpt,uint32_t update_type)199 int GptUpdateKernelEntry(GptData *gpt, uint32_t update_type)
200 {
201 	return GPT_SUCCESS;
202 }
203 
WriteAndFreeGptData(vb2ex_disk_handle_t disk_handle,GptData * gptdata)204 int WriteAndFreeGptData(vb2ex_disk_handle_t disk_handle, GptData *gptdata)
205 {
206 	return GPT_SUCCESS;
207 }
208 
GetCurrentKernelUniqueGuid(GptData * gpt,void * dest)209 void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
210 {
211 	static char fake_guid[] = "FakeGuid";
212 
213 	memcpy(dest, fake_guid, sizeof(fake_guid));
214 }
215 
vb2_unpack_key_buffer(struct vb2_public_key * key,const uint8_t * buf,uint32_t size)216 vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key,
217 				  const uint8_t *buf, uint32_t size)
218 {
219 	if (--unpack_key_fail == 0)
220 		return VB2_ERROR_MOCK;
221 
222 	return VB2_SUCCESS;
223 }
224 
vb2_verify_keyblock(struct vb2_keyblock * block,uint32_t size,const struct vb2_public_key * key,const struct vb2_workbuf * wb)225 vb2_error_t vb2_verify_keyblock(struct vb2_keyblock *block, uint32_t size,
226 				const struct vb2_public_key *key,
227 				const struct vb2_workbuf *wb)
228 {
229 	if (keyblock_verify_fail >= 1)
230 		return VB2_ERROR_MOCK;
231 
232 	/* Use this as an opportunity to override the keyblock */
233 	memcpy((void *)block, &cur_kbh, sizeof(cur_kbh));
234 
235 	return VB2_SUCCESS;
236 }
237 
vb2_verify_keyblock_hash(const struct vb2_keyblock * block,uint32_t size,const struct vb2_workbuf * wb)238 vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
239 				     uint32_t size,
240 				     const struct vb2_workbuf *wb)
241 {
242 	if (keyblock_verify_fail >= 2)
243 		return VB2_ERROR_MOCK;
244 
245 	/* Use this as an opportunity to override the keyblock */
246 	memcpy((void *)block, &cur_kbh, sizeof(cur_kbh));
247 
248 	return VB2_SUCCESS;
249 }
250 
vb2_verify_kernel_preamble(struct vb2_kernel_preamble * preamble,uint32_t size,const struct vb2_public_key * key,const struct vb2_workbuf * wb)251 vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
252 			       uint32_t size, const struct vb2_public_key *key,
253 			       const struct vb2_workbuf *wb)
254 {
255 	if (preamble_verify_fail)
256 		return VB2_ERROR_MOCK;
257 
258 	/* Use this as an opportunity to override the preamble */
259 	memcpy((void *)preamble, &kph, sizeof(kph));
260 	return VB2_SUCCESS;
261 }
262 
vb2_verify_data(const uint8_t * data,uint32_t size,struct vb2_signature * sig,const struct vb2_public_key * key,const struct vb2_workbuf * wb)263 vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
264 			    struct vb2_signature *sig,
265 			    const struct vb2_public_key *key,
266 			    const struct vb2_workbuf *wb)
267 {
268 	if (verify_data_fail)
269 		return VB2_ERROR_MOCK;
270 
271 	return VB2_SUCCESS;
272 }
273 
vb2_digest_finalize(struct vb2_digest_context * dc,uint8_t * digest,uint32_t digest_size)274 vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
275 				uint32_t digest_size)
276 {
277 	if (digest_size == sizeof(mock_digest))
278 		memcpy(digest, mock_digest, digest_size);
279 	else
280 		TEST_TRUE(false, "  unexpected digest size");
281 	return VB2_SUCCESS;
282 }
283 
284 /* Make sure nothing tested here ever calls this directly. */
vb2api_fail(struct vb2_context * c,uint8_t reason,uint8_t subcode)285 void vb2api_fail(struct vb2_context *c, uint8_t reason, uint8_t subcode)
286 {
287 	TEST_TRUE(0, "  called vb2api_fail()");
288 }
289 
test_load_kernel(vb2_error_t expect_retval,const char * test_name)290 static void test_load_kernel(vb2_error_t expect_retval, const char *test_name)
291 {
292 	TEST_EQ(vb2api_load_kernel(ctx, &lkp, &disk_info), expect_retval,
293 		test_name);
294 	if (expect_retval == VB2_SUCCESS)
295 		TEST_PTR_EQ(lkp.disk_handle, disk_info.handle,
296 			    "  fill disk_handle when success");
297 }
298 
299 /**
300  * Trivial invalid calls to vb2api_load_kernel()
301  */
invalid_params_tests(void)302 static void invalid_params_tests(void)
303 {
304 	ResetMocks();
305 	gpt_init_fail = 1;
306 	test_load_kernel(VB2_ERROR_LK_NO_KERNEL_FOUND, "Bad GPT");
307 
308 	/* This causes the stream open call to fail */
309 	ResetMocks();
310 	disk_info.handle = NULL;
311 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND, "Bad disk handle");
312 }
313 
load_kernel_tests(void)314 static void load_kernel_tests(void)
315 {
316 	ResetMocks();
317 	test_load_kernel(VB2_SUCCESS, "First kernel good");
318 	TEST_EQ(lkp.partition_number, 1, "  part num");
319 	TEST_EQ(lkp.bootloader_offset, 0xbeadd008, "  bootloader offset");
320 	TEST_EQ(lkp.bootloader_size, 0x1234, "  bootloader size");
321 	TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", "  guid");
322 	TEST_EQ(gpt_flag_external, 0, "GPT was internal");
323 	TEST_NEQ(sd->flags & VB2_SD_FLAG_KERNEL_SIGNED, 0, "  use signature");
324 
325 	ResetMocks();
326 	memcpy(&mock_parts[1].kbh, &mock_parts[0].kbh,
327 	       sizeof(mock_parts[0].kbh));
328 	mock_parts[1].e.starting_lba = 300;
329 	mock_parts[1].e.ending_lba = 449;
330 	test_load_kernel(VB2_SUCCESS, "Two good kernels");
331 	TEST_EQ(lkp.partition_number, 1, "  part num");
332 	TEST_EQ(mock_part_next, 1, "  didn't read second one");
333 
334 	/* Fail if no kernels found */
335 	ResetMocks();
336 	mock_parts[0].e.ending_lba = 0;
337 	test_load_kernel(VB2_ERROR_LK_NO_KERNEL_FOUND, "No kernels");
338 
339 	/* Skip kernels which are too small */
340 	ResetMocks();
341 	mock_parts[0].e.ending_lba = 109;
342 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND, "Too small");
343 
344 	ResetMocks();
345 	disk_read_to_fail = 100;
346 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
347 			 "Fail reading kernel start");
348 
349 	ResetMocks();
350 	keyblock_verify_fail = 1;
351 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
352 			 "Fail key block sig");
353 
354 	/* In dev mode, fail if hash is bad too */
355 	ResetMocks();
356 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
357 	keyblock_verify_fail = 2;
358 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
359 			 "Fail key block dev hash");
360 
361 	/* But just bad sig is ok */
362 	ResetMocks();
363 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
364 	keyblock_verify_fail = 1;
365 	test_load_kernel(VB2_SUCCESS, "Succeed keyblock dev sig");
366 	TEST_EQ(sd->flags & VB2_SD_FLAG_KERNEL_SIGNED, 0, "  use hash");
367 
368 	/* In dev mode and requiring signed kernel, fail if sig is bad */
369 	ResetMocks();
370 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
371 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
372 	keyblock_verify_fail = 1;
373 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
374 			 "Fail key block dev sig");
375 
376 	ResetMocks();
377 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
378 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY;
379 	keyblock_verify_fail = 1;
380 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
381 			 "Fail key block dev sig fwmp");
382 
383 	/* Check keyblock flags */
384 	ResetMocks();
385 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_0 |
386 					   VB2_KEYBLOCK_FLAG_DEVELOPER_1 |
387 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
388 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
389 			 "Keyblock dev flag mismatch");
390 
391 	ResetMocks();
392 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
393 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
394 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
395 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
396 			 "Keyblock rec flag mismatch");
397 
398 	ResetMocks();
399 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_0 |
400 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
401 					   VB2_KEYBLOCK_FLAG_MINIOS_1;
402 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
403 			 "Keyblock minios flag mismatch");
404 
405 	ResetMocks();
406 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
407 		      VB2_RECOVERY_RO_MANUAL);
408 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
409 					   VB2_KEYBLOCK_FLAG_DEVELOPER_1 |
410 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
411 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
412 			 "Keyblock recdev flag mismatch");
413 
414 	ResetMocks();
415 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
416 		      VB2_RECOVERY_RO_MANUAL);
417 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
418 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
419 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
420 	test_load_kernel(VB2_SUCCESS, "Keyblock rec flag okay");
421 
422 	ResetMocks();
423 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
424 		      VB2_RECOVERY_RO_MANUAL);
425 	ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
426 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
427 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
428 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
429 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
430 			 "Keyblock rec!dev flag mismatch");
431 
432 	ResetMocks();
433 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
434 		      VB2_RECOVERY_RO_MANUAL);
435 	ctx->flags |= VB2_CONTEXT_DEVELOPER_MODE;
436 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
437 					   VB2_KEYBLOCK_FLAG_DEVELOPER_1 |
438 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
439 	test_load_kernel(VB2_SUCCESS, "Keyblock recdev flag okay");
440 
441 	/* Check keyblock flags (dev mode + signed kernel required) */
442 	ResetMocks();
443 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
444 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
445 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
446 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
447 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
448 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
449 			 "Keyblock dev flag mismatch (signed kernel required)");
450 
451 	ResetMocks();
452 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
453 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY;
454 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_1 |
455 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
456 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
457 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
458 			 "Keyblock dev flag mismatch (signed kernel required)");
459 
460 	ResetMocks();
461 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
462 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY;
463 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_0 |
464 					   VB2_KEYBLOCK_FLAG_DEVELOPER_0 |
465 					   VB2_KEYBLOCK_FLAG_MINIOS_1;
466 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
467 			 "Keyblock dev flag mismatch (signed kernel required)");
468 
469 	ResetMocks();
470 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
471 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
472 	mock_parts[0].kbh.keyblock_flags = VB2_KEYBLOCK_FLAG_RECOVERY_0 |
473 					   VB2_KEYBLOCK_FLAG_DEVELOPER_1 |
474 					   VB2_KEYBLOCK_FLAG_MINIOS_0;
475 	test_load_kernel(VB2_SUCCESS,
476 			 "Keyblock dev flag okay (signed kernel required)");
477 
478 	/* Check kernel key version */
479 	ResetMocks();
480 	mock_parts[0].kbh.data_key.key_version = 1;
481 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
482 			 "Keyblock kernel key rollback");
483 
484 	ResetMocks();
485 	mock_parts[0].kbh.data_key.key_version = 0x10000;
486 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
487 			 "Keyblock kernel key version too big");
488 
489 	ResetMocks();
490 	mock_parts[0].kbh.data_key.key_version = 3;
491 	test_load_kernel(VB2_SUCCESS, "Keyblock version roll forward");
492 	TEST_EQ(sd->kernel_version, 0x30001, "  SD version");
493 	TEST_EQ(sd->kernel_version_secdata, 0x30001, "  SD write back");
494 
495 	ResetMocks();
496 	memcpy(&mock_parts[1].kbh, &mock_parts[0].kbh,
497 	       sizeof(mock_parts[0].kbh));
498 	mock_parts[0].kbh.data_key.key_version = 4;
499 	mock_parts[1].e.starting_lba = 300;
500 	mock_parts[1].e.ending_lba = 449;
501 	mock_parts[1].kbh.data_key.key_version = 3;
502 	test_load_kernel(VB2_SUCCESS, "Two kernels roll forward");
503 	TEST_EQ(mock_part_next, 2, "  read both");
504 	TEST_EQ(sd->kernel_version, 0x40001, "  SD version");
505 	TEST_EQ(sd->kernel_version_secdata, 0x30001, "  SD write back");
506 
507 	ResetMocks();
508 	mock_parts[0].kbh.data_key.key_version = 1;
509 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
510 	test_load_kernel(VB2_SUCCESS, "Key version ignored in dev mode");
511 
512 	ResetMocks();
513 	mock_parts[0].kbh.data_key.key_version = 1;
514 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
515 		      VB2_RECOVERY_RO_MANUAL);
516 	test_load_kernel(VB2_SUCCESS, "Key version ignored in rec mode");
517 
518 	ResetMocks();
519 	unpack_key_fail = 2;
520 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND, "Bad data key");
521 
522 	ResetMocks();
523 	preamble_verify_fail = 1;
524 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND, "Bad preamble");
525 
526 	ResetMocks();
527 	kph.kernel_version = 0;
528 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
529 			 "Kernel version rollback");
530 
531 	ResetMocks();
532 	kph.kernel_version = 0;
533 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
534 	test_load_kernel(VB2_SUCCESS, "Kernel version ignored in dev mode");
535 
536 	ResetMocks();
537 	kph.kernel_version = 0;
538 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
539 		      VB2_RECOVERY_RO_MANUAL);
540 	test_load_kernel(VB2_SUCCESS, "Kernel version ignored in rec mode");
541 
542 	/* Check kernel version (dev mode + signed kernel required) */
543 	ResetMocks();
544 	mock_parts[0].kbh.data_key.key_version = 0;
545 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
546 	vb2_nv_set(ctx, VB2_NV_DEV_BOOT_SIGNED_ONLY, 1);
547 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
548 			 "Keyblock key version checked in dev mode "
549 			 "(signed kernel required)");
550 
551 	ResetMocks();
552 	mock_parts[0].kbh.data_key.key_version = 0;
553 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
554 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY;
555 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
556 			 "Keyblock key version checked in dev mode "
557 			 "(signed kernel required)");
558 
559 	/* Check developer key hash - bad */
560 	ResetMocks();
561 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
562 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_USE_KEY_HASH;
563 	fwmp->dev_key_hash[0]++;
564 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
565 			 "Fail keyblock dev fwmp hash");
566 
567 	/* Check developer key hash - bad (recovery mode) */
568 	ResetMocks();
569 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_MANUAL_RECOVERY,
570 		      VB2_RECOVERY_RO_MANUAL);
571 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_USE_KEY_HASH;
572 	fwmp->dev_key_hash[0]++;
573 	test_load_kernel(VB2_SUCCESS,
574 			 "Bad keyblock dev fwmp hash ignored in rec mode");
575 
576 	/* Check developer key hash - good */
577 	ResetMocks();
578 	SET_BOOT_MODE(ctx, VB2_BOOT_MODE_DEVELOPER);
579 	fwmp->flags |= VB2_SECDATA_FWMP_DEV_USE_KEY_HASH;
580 	test_load_kernel(VB2_SUCCESS, "Good keyblock dev fwmp hash");
581 
582 	ResetMocks();
583 	kph.preamble_size |= 0x07;
584 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
585 			 "Kernel body offset");
586 
587 	ResetMocks();
588 	kph.preamble_size += 65536;
589 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
590 			 "Kernel body offset huge");
591 
592 	/* Check getting kernel load address from header */
593 	ResetMocks();
594 	kph.body_load_address = (size_t)kernel_buffer;
595 	lkp.kernel_buffer = NULL;
596 	test_load_kernel(VB2_SUCCESS, "Get load address from preamble");
597 	TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, "  address");
598 	/* Size is rounded up to nearest sector */
599 	TEST_EQ(lkp.kernel_buffer_size, 70144, "  size");
600 	/* Bootloader offset is relative to body load address */
601 	TEST_EQ(lkp.bootloader_offset, 0xbeadd008 - kph.body_load_address,
602 		"  bootloader offset");
603 
604 	ResetMocks();
605 	lkp.kernel_buffer_size = 8192;
606 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
607 			 "Kernel too big for buffer");
608 
609 	ResetMocks();
610 	mock_parts[0].e.ending_lba = 229;
611 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
612 			 "Kernel too big for partition");
613 
614 	ResetMocks();
615 	kph.body_signature.data_size = 8192;
616 	test_load_kernel(VB2_SUCCESS, "Kernel tiny");
617 
618 	ResetMocks();
619 	disk_read_to_fail = 228;
620 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND,
621 			 "Fail reading kernel data");
622 
623 	ResetMocks();
624 	verify_data_fail = 1;
625 	test_load_kernel(VB2_ERROR_LK_INVALID_KERNEL_FOUND, "Bad data");
626 
627 	/* Check that EXTERNAL_GPT flag makes it down */
628 	ResetMocks();
629 	disk_info.flags |= VB2_DISK_FLAG_EXTERNAL_GPT;
630 	test_load_kernel(VB2_SUCCESS, "Succeed external GPT");
631 	TEST_EQ(gpt_flag_external, 1, "GPT was external");
632 
633 	/* Check recovery from unreadble primary GPT */
634 	ResetMocks();
635 	disk_read_to_fail = 1;
636 	test_load_kernel(VB2_SUCCESS, "Can't read disk");
637 }
638 
main(void)639 int main(void)
640 {
641 	invalid_params_tests();
642 	load_kernel_tests();
643 
644 	return gTestSuccess ? 0 : 255;
645 }
646