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