1 /* Copyright (c) 2013 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 vboot_kernel.c
6  */
7 
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "cgptlib.h"
14 #include "cgptlib_internal.h"
15 #include "gbb_header.h"
16 #include "gpt.h"
17 #include "host_common.h"
18 #include "load_kernel_fw.h"
19 #include "test_common.h"
20 #include "vboot_api.h"
21 #include "vboot_common.h"
22 #include "vboot_kernel.h"
23 #include "vboot_nvstorage.h"
24 
25 #define LOGCALL(fmt, args...) sprintf(call_log + strlen(call_log), fmt, ##args)
26 #define TEST_CALLS(expect_log) TEST_STR_EQ(call_log, expect_log, "  calls")
27 
28 #define MOCK_SECTOR_SIZE  512
29 #define MOCK_SECTOR_COUNT 1024
30 
31 /* Mock kernel partition */
32 struct mock_part {
33 	uint32_t start;
34 	uint32_t size;
35 };
36 
37 /* Partition list; ends with a 0-size partition. */
38 #define MOCK_PART_COUNT 8
39 static struct mock_part mock_parts[MOCK_PART_COUNT];
40 static int mock_part_next;
41 
42 /* Mock data */
43 static char call_log[4096];
44 static uint8_t kernel_buffer[80000];
45 static int disk_read_to_fail;
46 static int disk_write_to_fail;
47 static int gpt_init_fail;
48 static int key_block_verify_fail;  /* 0=ok, 1=sig, 2=hash */
49 static int preamble_verify_fail;
50 static int verify_data_fail;
51 static RSAPublicKey *mock_data_key;
52 static int mock_data_key_allocated;
53 static int gpt_flag_external;
54 
55 static uint8_t gbb_data[sizeof(GoogleBinaryBlockHeader) + 2048];
56 static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader*)gbb_data;
57 static VbExDiskHandle_t handle;
58 static VbNvContext vnc;
59 static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
60 static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
61 static LoadKernelParams lkp;
62 static VbKeyBlockHeader kbh;
63 static VbKernelPreambleHeader kph;
64 static VbCommonParams cparams;
65 static uint8_t mock_disk[MOCK_SECTOR_SIZE * MOCK_SECTOR_COUNT];
66 static GptHeader *mock_gpt_primary =
67 	(GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * 1];
68 static GptHeader *mock_gpt_secondary =
69 	(GptHeader*)&mock_disk[MOCK_SECTOR_SIZE * (MOCK_SECTOR_COUNT - 1)];
70 
71 
72 /**
73  * Prepare a valid GPT header that will pass CheckHeader() tests
74  */
SetupGptHeader(GptHeader * h,int is_secondary)75 static void SetupGptHeader(GptHeader *h, int is_secondary)
76 {
77 	Memset(h, '\0', MOCK_SECTOR_SIZE);
78 
79 	/* "EFI PART" */
80 	memcpy(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE);
81 	h->revision = GPT_HEADER_REVISION;
82 	h->size = MIN_SIZE_OF_HEADER;
83 
84 	/* 16KB: 128 entries of 128 bytes */
85 	h->size_of_entry = sizeof(GptEntry);
86 	h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
87 
88 	/* Set LBA pointers for primary or secondary header */
89 	if (is_secondary) {
90 		h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
91 		h->entries_lba = h->my_lba - CalculateEntriesSectors(h);
92 	} else {
93 		h->my_lba = GPT_PMBR_SECTORS;
94 		h->entries_lba = h->my_lba + 1;
95 	}
96 
97 	h->first_usable_lba = 2 + CalculateEntriesSectors(h);
98 	h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h);
99 
100 	h->header_crc32 = HeaderCrc(h);
101 }
102 
ResetCallLog(void)103 static void ResetCallLog(void)
104 {
105 	*call_log = 0;
106 }
107 
108 /**
109  * Reset mock data (for use before each test)
110  */
ResetMocks(void)111 static void ResetMocks(void)
112 {
113 	ResetCallLog();
114 
115 	memset(&mock_disk, 0, sizeof(mock_disk));
116 	SetupGptHeader(mock_gpt_primary, 0);
117 	SetupGptHeader(mock_gpt_secondary, 1);
118 
119 	disk_read_to_fail = -1;
120 	disk_write_to_fail = -1;
121 
122 	gpt_init_fail = 0;
123 	key_block_verify_fail = 0;
124 	preamble_verify_fail = 0;
125 	verify_data_fail = 0;
126 
127 	mock_data_key = (RSAPublicKey *)"TestDataKey";
128 	mock_data_key_allocated = 0;
129 
130 	gpt_flag_external = 0;
131 
132 	memset(gbb, 0, sizeof(*gbb));
133 	gbb->major_version = GBB_MAJOR_VER;
134 	gbb->minor_version = GBB_MINOR_VER;
135 	gbb->flags = 0;
136 
137 	memset(&cparams, '\0', sizeof(cparams));
138 	cparams.gbb = gbb;
139 	cparams.gbb_data = gbb;
140 	cparams.gbb_size = sizeof(gbb_data);
141 
142 	memset(&vnc, 0, sizeof(vnc));
143 	VbNvSetup(&vnc);
144 	VbNvTeardown(&vnc);                   /* So CRC gets generated */
145 
146 	memset(&shared_data, 0, sizeof(shared_data));
147 	VbSharedDataInit(shared, sizeof(shared_data));
148 	shared->kernel_version_tpm = 0x20001;
149 
150 	memset(&lkp, 0, sizeof(lkp));
151 	lkp.nv_context = &vnc;
152 	lkp.shared_data_blob = shared;
153 	lkp.gbb_data = gbb;
154 	lkp.gbb_size = sizeof(gbb_data);
155 	lkp.bytes_per_lba = 512;
156 	lkp.streaming_lba_count = 1024;
157 	lkp.gpt_lba_count = 1024;
158 	lkp.kernel_buffer = kernel_buffer;
159 	lkp.kernel_buffer_size = sizeof(kernel_buffer);
160 	lkp.disk_handle = (VbExDiskHandle_t)1;
161 
162 	memset(&kbh, 0, sizeof(kbh));
163 	kbh.data_key.key_version = 2;
164 	kbh.key_block_flags = -1;
165 	kbh.key_block_size = sizeof(kbh);
166 
167 	memset(&kph, 0, sizeof(kph));
168 	kph.kernel_version = 1;
169 	kph.preamble_size = 4096 - kbh.key_block_size;
170 	kph.body_signature.data_size = 70144;
171 	kph.bootloader_address = 0xbeadd008;
172 	kph.bootloader_size = 0x1234;
173 
174 	memset(mock_parts, 0, sizeof(mock_parts));
175 	mock_parts[0].start = 100;
176 	mock_parts[0].size = 150;  /* 75 KB */
177 	mock_part_next = 0;
178 }
179 
180 /* Mocks */
181 
VbExDiskRead(VbExDiskHandle_t handle,uint64_t lba_start,uint64_t lba_count,void * buffer)182 VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start,
183                        uint64_t lba_count, void *buffer)
184 {
185 	LOGCALL("VbExDiskRead(h, %d, %d)\n", (int)lba_start, (int)lba_count);
186 
187 	if ((int)lba_start == disk_read_to_fail)
188 		return VBERROR_SIMULATED;
189 
190 	memcpy(buffer, &mock_disk[lba_start * MOCK_SECTOR_SIZE],
191 	       lba_count * MOCK_SECTOR_SIZE);
192 
193 	return VBERROR_SUCCESS;
194 }
195 
VbExDiskWrite(VbExDiskHandle_t handle,uint64_t lba_start,uint64_t lba_count,const void * buffer)196 VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start,
197 			uint64_t lba_count, const void *buffer)
198 {
199 	LOGCALL("VbExDiskWrite(h, %d, %d)\n", (int)lba_start, (int)lba_count);
200 
201 	if ((int)lba_start == disk_write_to_fail)
202 		return VBERROR_SIMULATED;
203 
204 	memcpy(&mock_disk[lba_start * MOCK_SECTOR_SIZE], buffer,
205 	       lba_count * MOCK_SECTOR_SIZE);
206 
207 	return VBERROR_SUCCESS;
208 }
209 
GptInit(GptData * gpt)210 int GptInit(GptData *gpt)
211 {
212 	return gpt_init_fail;
213 }
214 
GptNextKernelEntry(GptData * gpt,uint64_t * start_sector,uint64_t * size)215 int GptNextKernelEntry(GptData *gpt, uint64_t *start_sector, uint64_t *size)
216 {
217 	struct mock_part *p = mock_parts + mock_part_next;
218 
219 	if (!p->size)
220 		return GPT_ERROR_NO_VALID_KERNEL;
221 
222 	if (gpt->flags & GPT_FLAG_EXTERNAL)
223 		gpt_flag_external++;
224 
225 	gpt->current_kernel = mock_part_next;
226 	*start_sector = p->start;
227 	*size = p->size;
228 	mock_part_next++;
229 	return GPT_SUCCESS;
230 }
231 
GetCurrentKernelUniqueGuid(GptData * gpt,void * dest)232 void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest)
233 {
234 	static char fake_guid[] = "FakeGuid";
235 
236 	memcpy(dest, fake_guid, sizeof(fake_guid));
237 }
238 
KeyBlockVerify(const VbKeyBlockHeader * block,uint64_t size,const VbPublicKey * key,int hash_only)239 int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size,
240 		   const VbPublicKey *key, int hash_only) {
241 
242 	if (hash_only && key_block_verify_fail >= 2)
243 		return VBERROR_SIMULATED;
244 	else if (!hash_only && key_block_verify_fail >= 1)
245 		return VBERROR_SIMULATED;
246 
247 	/* Use this as an opportunity to override the key block */
248 	memcpy((void *)block, &kbh, sizeof(kbh));
249 	return VBERROR_SUCCESS;
250 }
251 
PublicKeyToRSA(const VbPublicKey * key)252 RSAPublicKey *PublicKeyToRSA(const VbPublicKey *key)
253 {
254 	TEST_EQ(mock_data_key_allocated, 0, "  mock data key not allocated");
255 
256 	if (mock_data_key)
257 		mock_data_key_allocated++;
258 
259 	return mock_data_key;
260 }
261 
RSAPublicKeyFree(RSAPublicKey * key)262 void RSAPublicKeyFree(RSAPublicKey* key)
263 {
264 	TEST_EQ(mock_data_key_allocated, 1, "  mock data key allocated");
265 	TEST_PTR_EQ(key, mock_data_key, "  data key ptr");
266 	mock_data_key_allocated--;
267 }
268 
VerifyKernelPreamble(const VbKernelPreambleHeader * preamble,uint64_t size,const RSAPublicKey * key)269 int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble,
270 			 uint64_t size, const RSAPublicKey *key)
271 {
272 	if (preamble_verify_fail)
273 		return VBERROR_SIMULATED;
274 
275 	/* Use this as an opportunity to override the preamble */
276 	memcpy((void *)preamble, &kph, sizeof(kph));
277 	return VBERROR_SUCCESS;
278 }
279 
VerifyData(const uint8_t * data,uint64_t size,const VbSignature * sig,const RSAPublicKey * key)280 int VerifyData(const uint8_t *data, uint64_t size, const VbSignature *sig,
281 	       const RSAPublicKey *key)
282 {
283 	if (verify_data_fail)
284 		return VBERROR_SIMULATED;
285 
286 	return VBERROR_SUCCESS;
287 }
288 
289 
290 /**
291  * Test reading/writing GPT
292  */
ReadWriteGptTest(void)293 static void ReadWriteGptTest(void)
294 {
295 	GptData g;
296 	GptHeader *h;
297 
298 	g.sector_bytes = MOCK_SECTOR_SIZE;
299 	g.streaming_drive_sectors = g.gpt_drive_sectors = MOCK_SECTOR_COUNT;
300 	g.valid_headers = g.valid_entries = MASK_BOTH;
301 
302 	ResetMocks();
303 	TEST_EQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead");
304 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
305 		   "VbExDiskRead(h, 2, 32)\n"
306 		   "VbExDiskRead(h, 1023, 1)\n"
307 		   "VbExDiskRead(h, 991, 32)\n");
308 	ResetCallLog();
309 	/*
310 	 * Valgrind complains about access to uninitialized memory here, so
311 	 * zero the primary header before each test.
312 	 */
313 	Memset(g.primary_header, '\0', g.sector_bytes);
314 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree");
315 	TEST_CALLS("");
316 
317 	/*
318 	 * Invalidate primary GPT header,
319 	 * check that AllocAndReadGptData still succeeds
320 	 */
321 	ResetMocks();
322 	Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
323 	TEST_EQ(AllocAndReadGptData(handle, &g), 0,
324 		"AllocAndRead primary invalid");
325 	TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
326                 g.gpt_drive_sectors, 0),
327                 1, "Primary header is invalid");
328 	TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
329 		g.gpt_drive_sectors, 0),
330                 0, "Secondary header is valid");
331 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
332 		   "VbExDiskRead(h, 1023, 1)\n"
333 		   "VbExDiskRead(h, 991, 32)\n");
334 	WriteAndFreeGptData(handle, &g);
335 
336 	/*
337 	 * Invalidate secondary GPT header,
338 	 * check that AllocAndReadGptData still succeeds
339 	 */
340 	ResetMocks();
341 	Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
342 	TEST_EQ(AllocAndReadGptData(handle, &g), 0,
343 		"AllocAndRead secondary invalid");
344 	TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
345 		g.gpt_drive_sectors, 0),
346                 0, "Primary header is valid");
347 	TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
348 		g.gpt_drive_sectors, 0),
349                 1, "Secondary header is invalid");
350 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
351 		   "VbExDiskRead(h, 2, 32)\n"
352 		   "VbExDiskRead(h, 1023, 1)\n");
353 	WriteAndFreeGptData(handle, &g);
354 
355 	/*
356 	 * Invalidate primary AND secondary GPT header,
357 	 * check that AllocAndReadGptData fails.
358 	 */
359 	ResetMocks();
360 	Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
361 	Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
362 	TEST_EQ(AllocAndReadGptData(handle, &g), 1,
363 		"AllocAndRead primary and secondary invalid");
364 	TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
365 		g.gpt_drive_sectors, 0),
366                 1, "Primary header is invalid");
367 	TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
368 		g.gpt_drive_sectors, 0),
369                 1, "Secondary header is invalid");
370 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
371 		   "VbExDiskRead(h, 1023, 1)\n");
372 	WriteAndFreeGptData(handle, &g);
373 
374 	/*
375 	 * Invalidate primary GPT header and check that it is
376 	 * repaired by GptRepair().
377 	 *
378 	 * This would normally be called by LoadKernel()->GptInit()
379 	 * but this callback is mocked in these tests.
380 	 */
381 	ResetMocks();
382 	Memset(mock_gpt_primary, '\0', sizeof(*mock_gpt_primary));
383 	TEST_EQ(AllocAndReadGptData(handle, &g), 0,
384 		"Fix Primary GPT: AllocAndRead");
385 	/* Call GptRepair() with input indicating secondary GPT is valid */
386 	g.valid_headers = g.valid_entries = MASK_SECONDARY;
387 	GptRepair(&g);
388 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
389 		"Fix Primary GPT: WriteAndFreeGptData");
390 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
391 		   "VbExDiskRead(h, 1023, 1)\n"
392 		   "VbExDiskRead(h, 991, 32)\n"
393 		   "VbExDiskWrite(h, 1, 1)\n"
394 		   "VbExDiskWrite(h, 2, 32)\n");
395 	TEST_EQ(CheckHeader(mock_gpt_primary, 0, g.streaming_drive_sectors,
396 		g.gpt_drive_sectors, 0),
397                 0, "Fix Primary GPT: Primary header is valid");
398 
399 	/*
400 	 * Invalidate secondary GPT header and check that it can be
401 	 * repaired by GptRepair().
402 	 *
403 	 * This would normally be called by LoadKernel()->GptInit()
404 	 * but this callback is mocked in these tests.
405 	 */
406 	ResetMocks();
407 	Memset(mock_gpt_secondary, '\0', sizeof(*mock_gpt_secondary));
408 	TEST_EQ(AllocAndReadGptData(handle, &g), 0,
409 		"Fix Secondary GPT: AllocAndRead");
410 	/* Call GptRepair() with input indicating primary GPT is valid */
411 	g.valid_headers = g.valid_entries = MASK_PRIMARY;
412 	GptRepair(&g);
413 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0,
414 		"Fix Secondary GPT: WriteAndFreeGptData");
415 	TEST_CALLS("VbExDiskRead(h, 1, 1)\n"
416 		   "VbExDiskRead(h, 2, 32)\n"
417 		   "VbExDiskRead(h, 1023, 1)\n"
418 		   "VbExDiskWrite(h, 1023, 1)\n"
419 		   "VbExDiskWrite(h, 991, 32)\n");
420 	TEST_EQ(CheckHeader(mock_gpt_secondary, 1, g.streaming_drive_sectors,
421 		g.gpt_drive_sectors, 0),
422                 0, "Fix Secondary GPT: Secondary header is valid");
423 
424 	/* Data which is changed is written */
425 	ResetMocks();
426 	AllocAndReadGptData(handle, &g);
427 	g.modified |= GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1;
428 	ResetCallLog();
429 	Memset(g.primary_header, '\0', g.sector_bytes);
430 	h = (GptHeader*)g.primary_header;
431 	h->entries_lba = 2;
432 	h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
433 	h->size_of_entry = sizeof(GptEntry);
434 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1");
435 	TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
436 		   "VbExDiskWrite(h, 2, 32)\n");
437 
438 	/* Data which is changed is written */
439 	ResetMocks();
440 	AllocAndReadGptData(handle, &g);
441 	g.modified = -1;
442 	ResetCallLog();
443 	Memset(g.primary_header, '\0', g.sector_bytes);
444 	h = (GptHeader*)g.primary_header;
445 	h->entries_lba = 2;
446 	h->number_of_entries = MAX_NUMBER_OF_ENTRIES;
447 	h->size_of_entry = sizeof(GptEntry);
448 	h = (GptHeader*)g.secondary_header;
449 	h->entries_lba = 991;
450 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
451 	TEST_CALLS("VbExDiskWrite(h, 1, 1)\n"
452 		   "VbExDiskWrite(h, 2, 32)\n"
453 		   "VbExDiskWrite(h, 1023, 1)\n"
454 		   "VbExDiskWrite(h, 991, 32)\n");
455 
456 	/* If legacy signature, don't modify GPT header/entries 1 */
457 	ResetMocks();
458 	AllocAndReadGptData(handle, &g);
459 	h = (GptHeader *)g.primary_header;
460 	memcpy(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE);
461 	g.modified = -1;
462 	ResetCallLog();
463 	TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");
464 	TEST_CALLS("VbExDiskWrite(h, 1023, 1)\n"
465 		   "VbExDiskWrite(h, 991, 32)\n");
466 
467 	/* Error reading */
468 	ResetMocks();
469 	disk_read_to_fail = 1;
470 	TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
471 	Memset(g.primary_header, '\0', g.sector_bytes);
472 	WriteAndFreeGptData(handle, &g);
473 
474 	ResetMocks();
475 	disk_read_to_fail = 2;
476 	TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
477 	Memset(g.primary_header, '\0', g.sector_bytes);
478 	WriteAndFreeGptData(handle, &g);
479 
480 	ResetMocks();
481 	disk_read_to_fail = 991;
482 	TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
483 	Memset(g.primary_header, '\0', g.sector_bytes);
484 	WriteAndFreeGptData(handle, &g);
485 
486 	ResetMocks();
487 	disk_read_to_fail = 1023;
488 	TEST_NEQ(AllocAndReadGptData(handle, &g), 0, "AllocAndRead disk fail");
489 	Memset(g.primary_header, '\0', g.sector_bytes);
490 	WriteAndFreeGptData(handle, &g);
491 
492 	/* Error writing */
493 	ResetMocks();
494 	disk_write_to_fail = 1;
495 	AllocAndReadGptData(handle, &g);
496 	g.modified = -1;
497 	Memset(g.primary_header, '\0', g.sector_bytes);
498 	TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
499 
500 	ResetMocks();
501 	disk_write_to_fail = 2;
502 	AllocAndReadGptData(handle, &g);
503 	g.modified = -1;
504 	Memset(g.primary_header, '\0', g.sector_bytes);
505 	h = (GptHeader*)g.primary_header;
506 	h->entries_lba = 2;
507 	TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
508 
509 	ResetMocks();
510 	disk_write_to_fail = 991;
511 	AllocAndReadGptData(handle, &g);
512 	g.modified = -1;
513 	Memset(g.primary_header, '\0', g.sector_bytes);
514 	TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
515 
516 	ResetMocks();
517 	disk_write_to_fail = 1023;
518 	AllocAndReadGptData(handle, &g);
519 	g.modified = -1;
520 	Memset(g.primary_header, '\0', g.sector_bytes);
521 	TEST_NEQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree disk fail");
522 
523 }
524 
525 /**
526  * Trivial invalid calls to LoadKernel()
527  */
InvalidParamsTest(void)528 static void InvalidParamsTest(void)
529 {
530 	ResetMocks();
531 	lkp.bytes_per_lba = 0;
532 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
533 		"Bad lba size");
534 
535 	ResetMocks();
536 	lkp.streaming_lba_count = 0;
537 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
538 		"Bad lba count");
539 
540 	ResetMocks();
541 	lkp.bytes_per_lba = 128*1024;
542 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_PARAMETER,
543 		"Huge lba size");
544 
545 	ResetMocks();
546 	disk_read_to_fail = 1;
547 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
548 		"Can't read disk");
549 
550 	ResetMocks();
551 	gpt_init_fail = 1;
552 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
553 		"Bad GPT");
554 
555 	ResetMocks();
556 	lkp.gpt_lba_count = 0;
557 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND,
558 		"GPT size = 0");
559 
560 	/* This causes the stream open call to fail */
561 	ResetMocks();
562 	lkp.disk_handle = NULL;
563 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
564 		"Bad disk handle");
565 }
566 
LoadKernelTest(void)567 static void LoadKernelTest(void)
568 {
569 	uint32_t u;
570 
571 	ResetMocks();
572 
573 	u = LoadKernel(&lkp, &cparams);
574 	TEST_EQ(u, 0, "First kernel good");
575 	TEST_EQ(lkp.partition_number, 1, "  part num");
576 	TEST_EQ(lkp.bootloader_address, 0xbeadd008, "  bootloader addr");
577 	TEST_EQ(lkp.bootloader_size, 0x1234, "  bootloader size");
578 	TEST_STR_EQ((char *)lkp.partition_guid, "FakeGuid", "  guid");
579 	TEST_EQ(gpt_flag_external, 0, "GPT was internal");
580 	VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
581 	TEST_EQ(u, 0, "  recovery request");
582 
583 	ResetMocks();
584 	mock_parts[1].start = 300;
585 	mock_parts[1].size = 150;
586 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two good kernels");
587 	TEST_EQ(lkp.partition_number, 1, "  part num");
588 	TEST_EQ(mock_part_next, 1, "  didn't read second one");
589 
590 	/* Fail if no kernels found */
591 	ResetMocks();
592 	mock_parts[0].size = 0;
593 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_NO_KERNEL_FOUND, "No kernels");
594 	VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
595 	TEST_EQ(u, VBNV_RECOVERY_RW_NO_OS, "  recovery request");
596 
597 	/* Skip kernels which are too small */
598 	ResetMocks();
599 	mock_parts[0].size = 10;
600 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND, "Too small");
601 	VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &u);
602 	TEST_EQ(u, VBNV_RECOVERY_RW_INVALID_OS, "  recovery request");
603 
604 	ResetMocks();
605 	disk_read_to_fail = 100;
606 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
607 		"Fail reading kernel start");
608 
609 	ResetMocks();
610 	key_block_verify_fail = 1;
611 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
612 		"Fail key block sig");
613 
614 	/* In dev mode, fail if hash is bad too */
615 	ResetMocks();
616 	lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
617 	key_block_verify_fail = 2;
618 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
619 		"Fail key block dev hash");
620 
621 	/* But just bad sig is ok */
622 	ResetMocks();
623 	lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
624 	key_block_verify_fail = 1;
625 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed key block dev sig");
626 
627 	/* In dev mode and requiring signed kernel, fail if sig is bad */
628 	ResetMocks();
629 	lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
630 	VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 1);
631 	VbNvTeardown(&vnc);
632 	key_block_verify_fail = 1;
633 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
634 		"Fail key block dev sig");
635 
636 	/* Check key block flag mismatches */
637 	ResetMocks();
638 	kbh.key_block_flags =
639 		KEY_BLOCK_FLAG_RECOVERY_0 | KEY_BLOCK_FLAG_DEVELOPER_1;
640 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
641 		"Key block dev flag mismatch");
642 
643 	ResetMocks();
644 	kbh.key_block_flags =
645 		KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
646 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
647 		"Key block rec flag mismatch");
648 
649 	ResetMocks();
650 	lkp.boot_flags |= BOOT_FLAG_RECOVERY;
651 	kbh.key_block_flags =
652 		KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_1;
653 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
654 		"Key block recdev flag mismatch");
655 
656 	ResetMocks();
657 	lkp.boot_flags |= BOOT_FLAG_RECOVERY | BOOT_FLAG_DEVELOPER;
658 	kbh.key_block_flags =
659 		KEY_BLOCK_FLAG_RECOVERY_1 | KEY_BLOCK_FLAG_DEVELOPER_0;
660 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
661 		"Key block rec!dev flag mismatch");
662 
663 	ResetMocks();
664 	kbh.data_key.key_version = 1;
665 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
666 		"Key block kernel key rollback");
667 
668 	ResetMocks();
669 	kbh.data_key.key_version = 0x10000;
670 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
671 		"Key block kernel key version too big");
672 
673 	ResetMocks();
674 	kbh.data_key.key_version = 3;
675 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key block version roll forward");
676 	TEST_EQ(shared->kernel_version_tpm, 0x30001, "  shared version");
677 
678 	ResetMocks();
679 	kbh.data_key.key_version = 3;
680 	mock_parts[1].start = 300;
681 	mock_parts[1].size = 150;
682 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Two kernels roll forward");
683 	TEST_EQ(mock_part_next, 2, "  read both");
684 	TEST_EQ(shared->kernel_version_tpm, 0x30001, "  shared version");
685 
686 	ResetMocks();
687 	kbh.data_key.key_version = 1;
688 	lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
689 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in dev mode");
690 
691 	ResetMocks();
692 	kbh.data_key.key_version = 1;
693 	lkp.boot_flags |= BOOT_FLAG_RECOVERY;
694 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Key version ignored in rec mode");
695 
696 	ResetMocks();
697 	mock_data_key = NULL;
698 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
699 		"Bad data key");
700 
701 	ResetMocks();
702 	preamble_verify_fail = 1;
703 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
704 		"Bad preamble");
705 
706 	ResetMocks();
707 	kph.kernel_version = 0;
708 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
709 		"Kernel version rollback");
710 
711 	ResetMocks();
712 	kph.kernel_version = 0;
713 	lkp.boot_flags |= BOOT_FLAG_DEVELOPER;
714 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in dev mode");
715 
716 	ResetMocks();
717 	kph.kernel_version = 0;
718 	lkp.boot_flags |= BOOT_FLAG_RECOVERY;
719 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel version ignored in rec mode");
720 
721 	ResetMocks();
722 	kph.preamble_size |= 0x07;
723 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
724 		"Kernel body offset");
725 
726 	ResetMocks();
727 	kph.preamble_size += 65536;
728 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
729 		"Kernel body offset huge");
730 
731 	/* Check getting kernel load address from header */
732 	ResetMocks();
733 	kph.body_load_address = (size_t)kernel_buffer;
734 	lkp.kernel_buffer = NULL;
735 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Get load address from preamble");
736 	TEST_PTR_EQ(lkp.kernel_buffer, kernel_buffer, "  address");
737 	/* Size is rounded up to nearest sector */
738 	TEST_EQ(lkp.kernel_buffer_size, 70144, "  size");
739 
740 	ResetMocks();
741 	lkp.kernel_buffer_size = 8192;
742 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
743 		"Kernel too big for buffer");
744 
745 	ResetMocks();
746 	mock_parts[0].size = 130;
747 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
748 		"Kernel too big for partition");
749 
750 	ResetMocks();
751 	kph.body_signature.data_size = 8192;
752 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Kernel tiny");
753 
754 	ResetMocks();
755 	disk_read_to_fail = 228;
756 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,
757 		"Fail reading kernel data");
758 
759 	ResetMocks();
760 	verify_data_fail = 1;
761 	TEST_EQ(LoadKernel(&lkp, &cparams), VBERROR_INVALID_KERNEL_FOUND,	"Bad data");
762 
763 	/* Check that EXTERNAL_GPT flag makes it down */
764 	ResetMocks();
765 	lkp.boot_flags |= BOOT_FLAG_EXTERNAL_GPT;
766 	TEST_EQ(LoadKernel(&lkp, &cparams), 0, "Succeed external GPT");
767 	TEST_EQ(gpt_flag_external, 1, "GPT was external");
768 }
769 
main(void)770 int main(void)
771 {
772 	ReadWriteGptTest();
773 	InvalidParamsTest();
774 	LoadKernelTest();
775 
776 	if (vboot_api_stub_check_memory())
777 		return 255;
778 
779 	return gTestSuccess ? 0 : 255;
780 }
781