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 */ 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 103 static void ResetCallLog(void) 104 { 105 *call_log = 0; 106 } 107 108 /** 109 * Reset mock data (for use before each test) 110 */ 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 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 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 210 int GptInit(GptData *gpt) 211 { 212 return gpt_init_fail; 213 } 214 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 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 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 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 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 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 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 */ 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 */ 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 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 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