Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: src/platform/vboot_reference/utils/kernel_image.c

Issue 1599001: VBoot Reference: Refactor Pass 1: Split {firmware|kernel}_image (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Functions for generating and manipulating a verified boot kernel image. 5 * Functions for generating and manipulating a verified boot kernel image.
6 * (Userland portion)
6 */ 7 */
7 8
8 #include "kernel_image.h" 9 #include "kernel_image.h"
9 10
10 #include <fcntl.h> 11 #include <fcntl.h>
11 #include <stdio.h> 12 #include <stdio.h>
12 #include <sys/types.h> 13 #include <sys/types.h>
13 #include <sys/stat.h> 14 #include <sys/stat.h>
14 #include <unistd.h> 15 #include <unistd.h>
15 16
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 image_len = file_size; 69 image_len = file_size;
69 70
70 st.remaining_len = image_len; 71 st.remaining_len = image_len;
71 st.remaining_buf = kernel_buf; 72 st.remaining_buf = kernel_buf;
72 st.overrun = 0; 73 st.overrun = 0;
73 74
74 /* Read and compare magic bytes. */ 75 /* Read and compare magic bytes. */
75 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE); 76 StatefulMemcpy(&st, &image->magic, KERNEL_MAGIC_SIZE);
76 77
77 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) { 78 if (SafeMemcmp(image->magic, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) {
78 fprintf(stderr, "Wrong Kernel Magic.\n"); 79 debug("Wrong Kernel Magic.\n");
79 Free(kernel_buf); 80 Free(kernel_buf);
80 return NULL; 81 return NULL;
81 } 82 }
82 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version)); 83 StatefulMemcpy(&st, &image->header_version, FIELD_LEN(header_version));
83 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); 84 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
84 StatefulMemcpy(&st, &image->firmware_sign_algorithm, 85 StatefulMemcpy(&st, &image->firmware_sign_algorithm,
85 FIELD_LEN(firmware_sign_algorithm)); 86 FIELD_LEN(firmware_sign_algorithm));
86 StatefulMemcpy(&st, &image->kernel_sign_algorithm, 87 StatefulMemcpy(&st, &image->kernel_sign_algorithm,
87 FIELD_LEN(kernel_sign_algorithm)); 88 FIELD_LEN(kernel_sign_algorithm));
88 89
(...skipping 11 matching lines...) Expand all
100 101
101 /* Compute size of pre-processed RSA public keys and signatures. */ 102 /* Compute size of pre-processed RSA public keys and signatures. */
102 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); 103 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm);
103 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; 104 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm];
104 kernel_sign_key_len = RSAProcessedKeySize(image->kernel_sign_algorithm); 105 kernel_sign_key_len = RSAProcessedKeySize(image->kernel_sign_algorithm);
105 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; 106 kernel_signature_len = siglen_map[image->kernel_sign_algorithm];
106 107
107 /* Check whether key header length is correct. */ 108 /* Check whether key header length is correct. */
108 header_len = GetKernelHeaderLen(image); 109 header_len = GetKernelHeaderLen(image);
109 if (header_len != image->header_len) { 110 if (header_len != image->header_len) {
110 fprintf(stderr, "Header length mismatch. Got: %d, Expected: %d\n", 111 debug("Header length mismatch. Got: %d, Expected: %d\n",
111 image->header_len, header_len); 112 image->header_len, header_len);
112 Free(kernel_buf); 113 Free(kernel_buf);
113 return NULL; 114 return NULL;
114 } 115 }
115 116
116 /* Read pre-processed public half of the kernel signing key. */ 117 /* Read pre-processed public half of the kernel signing key. */
117 StatefulMemcpy(&st, &image->kernel_key_version, 118 StatefulMemcpy(&st, &image->kernel_key_version,
118 FIELD_LEN(kernel_key_version)); 119 FIELD_LEN(kernel_key_version));
119 image->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len); 120 image->kernel_sign_key = (uint8_t*) Malloc(kernel_sign_key_len);
120 StatefulMemcpy(&st, image->kernel_sign_key, kernel_sign_key_len); 121 StatefulMemcpy(&st, image->kernel_sign_key, kernel_sign_key_len);
121 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); 122 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
122 123
123 /* Check whether the header checksum matches. */ 124 /* Check whether the header checksum matches. */
124 CalculateKernelHeaderChecksum(image, header_checksum); 125 CalculateKernelHeaderChecksum(image, header_checksum);
125 if (SafeMemcmp(header_checksum, image->header_checksum, 126 if (SafeMemcmp(header_checksum, image->header_checksum,
126 FIELD_LEN(header_checksum))) { 127 FIELD_LEN(header_checksum))) {
127 fprintf(stderr, "Invalid kernel header checksum!\n"); 128 debug("Invalid kernel header checksum!\n");
128 Free(kernel_buf); 129 Free(kernel_buf);
129 return NULL; 130 return NULL;
130 } 131 }
131 132
132 /* Read key signature. */ 133 /* Read key signature. */
133 image->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len); 134 image->kernel_key_signature = (uint8_t*) Malloc(kernel_key_signature_len);
134 StatefulMemcpy(&st, image->kernel_key_signature, 135 StatefulMemcpy(&st, image->kernel_key_signature,
135 kernel_key_signature_len); 136 kernel_key_signature_len);
136 137
137 /* Read the kernel config. */ 138 /* Read the kernel config. */
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 301
301 int WriteKernelImage(const char* input_file, 302 int WriteKernelImage(const char* input_file,
302 const KernelImage* image) { 303 const KernelImage* image) {
303 int fd; 304 int fd;
304 uint8_t* kernel_blob; 305 uint8_t* kernel_blob;
305 uint64_t blob_len; 306 uint64_t blob_len;
306 307
307 if (!image) 308 if (!image)
308 return 0; 309 return 0;
309 if (-1 == (fd = creat(input_file, S_IRWXU))) { 310 if (-1 == (fd = creat(input_file, S_IRWXU))) {
310 fprintf(stderr, "Couldn't open file for writing kernel image: %s\n", 311 debug("Couldn't open file for writing kernel image: %s\n",
311 input_file); 312 input_file);
312 return 0; 313 return 0;
313 } 314 }
314 kernel_blob = GetKernelBlob(image, &blob_len); 315 kernel_blob = GetKernelBlob(image, &blob_len);
315 if (!kernel_blob) { 316 if (!kernel_blob) {
316 fprintf(stderr, "Couldn't create kernel blob from KernelImage.\n"); 317 debug("Couldn't create kernel blob from KernelImage.\n");
317 return 0; 318 return 0;
318 } 319 }
319 if (blob_len != write(fd, kernel_blob, blob_len)) { 320 if (blob_len != write(fd, kernel_blob, blob_len)) {
320 fprintf(stderr, "Couldn't write Kernel Image to file: %s\n", 321 debug("Couldn't write Kernel Image to file: %s\n",
321 input_file); 322 input_file);
322 323
323 Free(kernel_blob); 324 Free(kernel_blob);
324 close(fd); 325 close(fd);
325 return 0; 326 return 0;
326 } 327 }
327 Free(kernel_blob); 328 Free(kernel_blob);
328 close(fd); 329 close(fd);
329 return 1; 330 return 1;
330 } 331 }
(...skipping 23 matching lines...) Expand all
354 "Kernel Entry Address = %" PRId64 "\n\n", 355 "Kernel Entry Address = %" PRId64 "\n\n",
355 image->kernel_version, 356 image->kernel_version,
356 image->options.version[0], image->options.version[1], 357 image->options.version[0], image->options.version[1],
357 image->options.cmd_line, 358 image->options.cmd_line,
358 image->options.kernel_len, 359 image->options.kernel_len,
359 image->options.kernel_load_addr, 360 image->options.kernel_load_addr,
360 image->options.kernel_entry_addr); 361 image->options.kernel_entry_addr);
361 /* TODO(gauravsh): Output kernel signature here? */ 362 /* TODO(gauravsh): Output kernel signature here? */
362 } 363 }
363 364
364 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = {
365 "Success.",
366 "Invalid Image.",
367 "Kernel Key Signature Failed.",
368 "Invalid Kernel Verification Algorithm.",
369 "Config Signature Failed.",
370 "Kernel Signature Failed.",
371 "Wrong Kernel Magic.",
372 };
373
374 int VerifyKernelHeader(const uint8_t* firmware_key_blob,
375 const uint8_t* header_blob,
376 const int dev_mode,
377 int* firmware_algorithm,
378 int* kernel_algorithm,
379 int* kernel_header_len) {
380 int kernel_sign_key_len;
381 int firmware_sign_key_len;
382 uint16_t header_version, header_len;
383 uint16_t firmware_sign_algorithm, kernel_sign_algorithm;
384 uint8_t* header_checksum = NULL;
385
386 /* Base Offset for the header_checksum field. Actual offset is
387 * this + kernel_sign_key_len. */
388 int base_header_checksum_offset = (FIELD_LEN(header_version) +
389 FIELD_LEN(header_len) +
390 FIELD_LEN(firmware_sign_algorithm) +
391 FIELD_LEN(kernel_sign_algorithm) +
392 FIELD_LEN(kernel_key_version));
393
394 Memcpy(&header_version, header_blob, sizeof(header_version));
395 Memcpy(&header_len, header_blob + FIELD_LEN(header_version),
396 sizeof(header_len));
397 Memcpy(&firmware_sign_algorithm,
398 header_blob + (FIELD_LEN(header_version) +
399 FIELD_LEN(header_len)),
400 sizeof(firmware_sign_algorithm));
401 Memcpy(&kernel_sign_algorithm,
402 header_blob + (FIELD_LEN(header_version) +
403 FIELD_LEN(header_len) +
404 FIELD_LEN(firmware_sign_algorithm)),
405 sizeof(kernel_sign_algorithm));
406
407 /* TODO(gauravsh): Make this return two different error types depending
408 * on whether the firmware or kernel signing algorithm is invalid. */
409 if (firmware_sign_algorithm >= kNumAlgorithms)
410 return VERIFY_KERNEL_INVALID_ALGORITHM;
411 if (kernel_sign_algorithm >= kNumAlgorithms)
412 return VERIFY_KERNEL_INVALID_ALGORITHM;
413
414 *firmware_algorithm = (int) firmware_sign_algorithm;
415 *kernel_algorithm = (int) kernel_sign_algorithm;
416 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm);
417 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm);
418
419
420 /* Verify if header len is correct? */
421 if (header_len != (base_header_checksum_offset +
422 kernel_sign_key_len +
423 FIELD_LEN(header_checksum))) {
424 fprintf(stderr, "VerifyKernelHeader: Header length mismatch\n");
425 return VERIFY_KERNEL_INVALID_IMAGE;
426 }
427 *kernel_header_len = (int) header_len;
428
429 /* Verify if the hash of the header is correct. */
430 header_checksum = DigestBuf(header_blob,
431 header_len - FIELD_LEN(header_checksum),
432 SHA512_DIGEST_ALGORITHM);
433 if (SafeMemcmp(header_checksum,
434 header_blob + (base_header_checksum_offset +
435 kernel_sign_key_len),
436 FIELD_LEN(header_checksum))) {
437 Free(header_checksum);
438 fprintf(stderr, "VerifyKernelHeader: Invalid header hash\n");
439 return VERIFY_KERNEL_INVALID_IMAGE;
440 }
441 Free(header_checksum);
442
443 /* Verify kernel key signature unless we are in dev mode. */
444 if (!dev_mode) {
445 if (!RSAVerifyBinary_f(firmware_key_blob, NULL, /* Key to use */
446 header_blob, /* Data to verify */
447 header_len, /* Length of data */
448 header_blob + header_len, /* Expected Signature */
449 firmware_sign_algorithm))
450 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
451 }
452 return 0;
453 }
454
455 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key,
456 const uint8_t* config_blob,
457 int algorithm,
458 uint64_t* kernel_len) {
459 uint64_t len;
460 int config_len;
461 config_len = GetKernelConfigLen(NULL);
462 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */
463 config_blob, /* Data to verify */
464 config_len, /* Length of data */
465 config_blob + config_len, /* Expected Signature */
466 algorithm))
467 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
468
469 Memcpy(&len,
470 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
471 FIELD_LEN(options.cmd_line)),
472 sizeof(len));
473 *kernel_len = len;
474 return 0;
475 }
476
477 int VerifyKernelData(RSAPublicKey* kernel_sign_key,
478 const uint8_t* kernel_config_start,
479 const uint8_t* kernel_data_start,
480 uint64_t kernel_len,
481 int algorithm) {
482 int signature_len = siglen_map[algorithm];
483 uint8_t* digest;
484 DigestContext ctx;
485
486 /* Since the kernel signature is computed over the kernel version, options
487 * and data, which does not form a contiguous region of memory, we calculate
488 * the message digest ourselves. */
489 DigestInit(&ctx, algorithm);
490 DigestUpdate(&ctx, kernel_config_start, GetKernelConfigLen());
491 DigestUpdate(&ctx, kernel_data_start + signature_len, kernel_len);
492 digest = DigestFinal(&ctx);
493 if (!RSAVerifyBinaryWithDigest_f(
494 NULL, kernel_sign_key, /* Key to use. */
495 digest, /* Digest of the data to verify. */
496 kernel_data_start, /* Expected Signature */
497 algorithm)) {
498 Free(digest);
499 return VERIFY_KERNEL_SIGNATURE_FAILED;
500 }
501 Free(digest);
502 return 0;
503 }
504
505 int VerifyKernel(const uint8_t* firmware_key_blob,
506 const uint8_t* kernel_blob,
507 const int dev_mode) {
508 int error_code;
509 int firmware_sign_algorithm; /* Firmware signing key algorithm. */
510 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */
511 RSAPublicKey* kernel_sign_key;
512 int kernel_sign_key_len, kernel_key_signature_len, kernel_signature_len,
513 header_len;
514 uint64_t kernel_len;
515 const uint8_t* header_ptr; /* Pointer to header. */
516 const uint8_t* kernel_sign_key_ptr; /* Pointer to signing key. */
517 const uint8_t* config_ptr; /* Pointer to kernel config block. */
518 const uint8_t* kernel_ptr; /* Pointer to kernel signature/data. */
519
520 /* Note: All the offset calculations are based on struct FirmwareImage which
521 * is defined in include/firmware_image.h. */
522
523 /* Compare magic bytes. */
524 if (SafeMemcmp(kernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE))
525 return VERIFY_KERNEL_WRONG_MAGIC;
526 header_ptr = kernel_blob + KERNEL_MAGIC_SIZE;
527
528 /* Only continue if header verification succeeds. */
529 if ((error_code = VerifyKernelHeader(firmware_key_blob, header_ptr, dev_mode,
530 &firmware_sign_algorithm,
531 &kernel_sign_algorithm, &header_len))) {
532 fprintf(stderr, "VerifyKernel: Kernel header verification failed.\n");
533 return error_code; /* AKA jump to recovery. */
534 }
535 /* Parse signing key into RSAPublicKey structure since it is required multiple
536 * times. */
537 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm);
538 kernel_sign_key_ptr = header_ptr + (FIELD_LEN(header_version) +
539 FIELD_LEN(header_len) +
540 FIELD_LEN(firmware_sign_algorithm) +
541 FIELD_LEN(kernel_sign_algorithm) +
542 FIELD_LEN(kernel_key_version));
543 kernel_sign_key = RSAPublicKeyFromBuf(kernel_sign_key_ptr,
544 kernel_sign_key_len);
545 kernel_signature_len = siglen_map[kernel_sign_algorithm];
546 kernel_key_signature_len = siglen_map[firmware_sign_algorithm];
547
548 /* Only continue if config verification succeeds. */
549 config_ptr = (header_ptr + header_len + kernel_key_signature_len);
550 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr,
551 kernel_sign_algorithm,
552 &kernel_len))) {
553 RSAPublicKeyFree(kernel_sign_key);
554 return error_code; /* AKA jump to recovery. */
555 }
556 /* Only continue if kernel data verification succeeds. */
557 kernel_ptr = (config_ptr +
558 GetKernelConfigLen() + /* Skip config block/signature. */
559 kernel_signature_len);
560
561 if ((error_code = VerifyKernelData(kernel_sign_key, config_ptr, kernel_ptr,
562 kernel_len,
563 kernel_sign_algorithm))) {
564 RSAPublicKeyFree(kernel_sign_key);
565 return error_code; /* AKA jump to recovery. */
566 }
567 RSAPublicKeyFree(kernel_sign_key);
568 return 0; /* Success! */
569 }
570 365
571 int VerifyKernelImage(const RSAPublicKey* firmware_key, 366 int VerifyKernelImage(const RSAPublicKey* firmware_key,
572 const KernelImage* image, 367 const KernelImage* image,
573 const int dev_mode) { 368 const int dev_mode) {
574 RSAPublicKey* kernel_sign_key = NULL; 369 RSAPublicKey* kernel_sign_key = NULL;
575 uint8_t* header_digest = NULL; 370 uint8_t* header_digest = NULL;
576 uint8_t* config_digest = NULL; 371 uint8_t* config_digest = NULL;
577 uint8_t* kernel_digest = NULL; 372 uint8_t* kernel_digest = NULL;
578 int kernel_sign_key_size; 373 int kernel_sign_key_size;
579 int kernel_signature_size; 374 int kernel_signature_size;
(...skipping 30 matching lines...) Expand all
610 FIELD_LEN(kernel_key_version)); 405 FIELD_LEN(kernel_key_version));
611 DigestUpdate(&ctx, image->kernel_sign_key, 406 DigestUpdate(&ctx, image->kernel_sign_key,
612 RSAProcessedKeySize(image->kernel_sign_algorithm)); 407 RSAProcessedKeySize(image->kernel_sign_algorithm));
613 DigestUpdate(&ctx, image->header_checksum, 408 DigestUpdate(&ctx, image->header_checksum,
614 FIELD_LEN(header_checksum)); 409 FIELD_LEN(header_checksum));
615 header_digest = DigestFinal(&ctx); 410 header_digest = DigestFinal(&ctx);
616 if (!RSAVerify(firmware_key, image->kernel_key_signature, 411 if (!RSAVerify(firmware_key, image->kernel_key_signature,
617 siglen_map[image->firmware_sign_algorithm], 412 siglen_map[image->firmware_sign_algorithm],
618 image->firmware_sign_algorithm, 413 image->firmware_sign_algorithm,
619 header_digest)) { 414 header_digest)) {
620 fprintf(stderr, "VerifyKernelImage(): Key signature check failed.\n"); 415 debug("VerifyKernelImage(): Key signature check failed.\n");
621 error_code = VERIFY_KERNEL_KEY_SIGNATURE_FAILED; 416 error_code = VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
622 goto verify_failure; 417 goto verify_failure;
623 } 418 }
624 } 419 }
625 420
626 /* Get kernel signing key to verify the rest of the kernel. */ 421 /* Get kernel signing key to verify the rest of the kernel. */
627 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm); 422 kernel_sign_key_size = RSAProcessedKeySize(image->kernel_sign_algorithm);
628 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key, 423 kernel_sign_key = RSAPublicKeyFromBuf(image->kernel_sign_key,
629 kernel_sign_key_size); 424 kernel_sign_key_size);
630 kernel_signature_size = siglen_map[image->kernel_sign_algorithm]; 425 kernel_signature_size = siglen_map[image->kernel_sign_algorithm];
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 uint8_t* config_signature = NULL; 511 uint8_t* config_signature = NULL;
717 uint8_t* kernel_signature = NULL; 512 uint8_t* kernel_signature = NULL;
718 uint8_t* kernel_buf; 513 uint8_t* kernel_buf;
719 int signature_len = siglen_map[image->kernel_sign_algorithm]; 514 int signature_len = siglen_map[image->kernel_sign_algorithm];
720 515
721 config_blob = GetKernelConfigBlob(image); 516 config_blob = GetKernelConfigBlob(image);
722 if (!(config_signature = SignatureBuf(config_blob, 517 if (!(config_signature = SignatureBuf(config_blob,
723 GetKernelConfigLen(), 518 GetKernelConfigLen(),
724 kernel_signing_key_file, 519 kernel_signing_key_file,
725 image->kernel_sign_algorithm))) { 520 image->kernel_sign_algorithm))) {
726 fprintf(stderr, "Could not compute signature on the kernel config.\n"); 521 debug("Could not compute signature on the kernel config.\n");
727 Free(config_blob); 522 Free(config_blob);
728 return 0; 523 return 0;
729 } 524 }
730 525
731 image->config_signature = (uint8_t*) Malloc(signature_len); 526 image->config_signature = (uint8_t*) Malloc(signature_len);
732 Memcpy(image->config_signature, config_signature, signature_len); 527 Memcpy(image->config_signature, config_signature, signature_len);
733 Free(config_signature); 528 Free(config_signature);
734 /* Kernel signature muse be calculated on the kernel version, options and 529 /* Kernel signature muse be calculated on the kernel version, options and
735 * kernel data to avoid splicing attacks. */ 530 * kernel data to avoid splicing attacks. */
736 kernel_buf = (uint8_t*) Malloc(GetKernelConfigLen() + 531 kernel_buf = (uint8_t*) Malloc(GetKernelConfigLen() +
737 image->options.kernel_len); 532 image->options.kernel_len);
738 Memcpy(kernel_buf, config_blob, GetKernelConfigLen()); 533 Memcpy(kernel_buf, config_blob, GetKernelConfigLen());
739 Memcpy(kernel_buf + GetKernelConfigLen(), image->kernel_data, 534 Memcpy(kernel_buf + GetKernelConfigLen(), image->kernel_data,
740 image->options.kernel_len); 535 image->options.kernel_len);
741 if (!(kernel_signature = SignatureBuf(kernel_buf, 536 if (!(kernel_signature = SignatureBuf(kernel_buf,
742 GetKernelConfigLen() + 537 GetKernelConfigLen() +
743 image->options.kernel_len, 538 image->options.kernel_len,
744 kernel_signing_key_file, 539 kernel_signing_key_file,
745 image->kernel_sign_algorithm))) { 540 image->kernel_sign_algorithm))) {
746 Free(config_blob); 541 Free(config_blob);
747 Free(kernel_buf); 542 Free(kernel_buf);
748 fprintf(stderr, "Could not compute signature on the kernel.\n"); 543 debug("Could not compute signature on the kernel.\n");
749 return 0; 544 return 0;
750 } 545 }
751 image->kernel_signature = (uint8_t*) Malloc(signature_len); 546 image->kernel_signature = (uint8_t*) Malloc(signature_len);
752 Memcpy(image->kernel_signature, kernel_signature, signature_len); 547 Memcpy(image->kernel_signature, kernel_signature, signature_len);
753 Free(kernel_signature); 548 Free(kernel_signature);
754 Free(kernel_buf); 549 Free(kernel_buf);
755 Free(config_blob); 550 Free(config_blob);
756 return 1; 551 return 1;
757 } 552 }
758 553
759 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { 554 void PrintKernelEntry(kernel_entry* entry) {
760 uint8_t* kernel_ptr; 555 debug("Boot Priority = %d\n", entry->boot_priority);
761 uint16_t kernel_key_version; 556 debug("Boot Tries Remaining = %d\n", entry->boot_tries_remaining);
762 uint16_t kernel_version; 557 debug("Boot Success Flag = %d\n", entry->boot_success_flag);
763 uint16_t firmware_sign_algorithm;
764 uint16_t kernel_sign_algorithm;
765 int kernel_key_signature_len;
766 int kernel_sign_key_len;
767 kernel_ptr = kernel_blob + (FIELD_LEN(magic) +
768 FIELD_LEN(header_version) +
769 FIELD_LEN(header_len));
770 Memcpy(&firmware_sign_algorithm, kernel_ptr, sizeof(firmware_sign_algorithm));
771 kernel_ptr += FIELD_LEN(firmware_sign_algorithm);
772 Memcpy(&kernel_sign_algorithm, kernel_ptr, sizeof(kernel_sign_algorithm));
773 kernel_ptr += FIELD_LEN(kernel_sign_algorithm);
774 Memcpy(&kernel_key_version, kernel_ptr, sizeof(kernel_key_version));
775
776 if (firmware_sign_algorithm >= kNumAlgorithms)
777 return 0;
778 if (kernel_sign_algorithm >= kNumAlgorithms)
779 return 0;
780 kernel_key_signature_len = siglen_map[firmware_sign_algorithm];
781 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm);
782 kernel_ptr += (FIELD_LEN(kernel_key_version) +
783 kernel_sign_key_len +
784 FIELD_LEN(header_checksum) +
785 kernel_key_signature_len);
786 Memcpy(&kernel_version, kernel_ptr, sizeof(kernel_version));
787 return CombineUint16Pair(kernel_key_version, kernel_version);
788 } 558 }
789
790 void PrintKernelEntry(kernel_entry* entry) {
791 fprintf(stderr, "Boot Priority = %d\n", entry->boot_priority);
792 fprintf(stderr, "Boot Tries Remaining = %d\n", entry->boot_tries_remaining);
793 fprintf(stderr, "Boot Success Flag = %d\n", entry->boot_success_flag);
794 }
795
796 int VerifyKernelDriver_f(uint8_t* firmware_key_blob,
797 kernel_entry* kernelA,
798 kernel_entry* kernelB,
799 int dev_mode) {
800 int i;
801 /* Contains the logical kernel version (32-bit) which is calculated as
802 * (kernel_key_version << 16 | kernel_version) where
803 * [kernel_key_version], [firmware_version] are both 16-bit.
804 */
805 uint32_t kernelA_lversion, kernelB_lversion;
806 uint32_t min_lversion; /* Minimum of kernel A and kernel B lversion. */
807 uint32_t stored_lversion; /* Stored logical version in the TPM. */
808 kernel_entry* try_kernel[2]; /* Kernel in try order. */
809 int try_kernel_which[2]; /* Which corresponding kernel in the try order */
810 uint32_t try_kernel_lversion[2]; /* Their logical versions. */
811
812 /* [kernel_to_boot] will eventually contain the boot path to follow
813 * and is returned to the caller. Initially, we set it to recovery. If
814 * a valid bootable kernel is found, it will be set to that. */
815 int kernel_to_boot = BOOT_KERNEL_RECOVERY_CONTINUE;
816
817
818 /* The TPM must already have be initialized, so no need to call SetupTPM(). */
819
820 /* We get the key versions by reading directly from the image blobs without
821 * any additional (expensive) sanity checking on the blob since it's faster to
822 * outright reject a kernel with an older kernel key version. A malformed
823 * or corrupted kernel blob will still fail when VerifyKernel() is called
824 * on it.
825 */
826 kernelA_lversion = GetLogicalKernelVersion(kernelA->kernel_blob);
827 kernelB_lversion = GetLogicalKernelVersion(kernelB->kernel_blob);
828 min_lversion = Min(kernelA_lversion, kernelB_lversion);
829 stored_lversion = CombineUint16Pair(GetStoredVersion(KERNEL_KEY_VERSION),
830 GetStoredVersion(KERNEL_VERSION));
831
832 /* TODO(gauravsh): The kernel entries kernelA and kernelB come from the
833 * partition table - verify its signature/checksum before proceeding
834 * further. */
835
836 /* The logic for deciding which kernel to boot from is taken from the
837 * the Chromium OS Drive Map design document.
838 *
839 * We went to consider the kernels in their according to their boot
840 * priority attribute value.
841 */
842
843 if (kernelA->boot_priority >= kernelB->boot_priority) {
844 try_kernel[0] = kernelA;
845 try_kernel_which[0] = BOOT_KERNEL_A_CONTINUE;
846 try_kernel_lversion[0] = kernelA_lversion;
847 try_kernel[1] = kernelB;
848 try_kernel_which[1] = BOOT_KERNEL_B_CONTINUE;
849 try_kernel_lversion[1] = kernelB_lversion;
850 } else {
851 try_kernel[0] = kernelB;
852 try_kernel_which[0] = BOOT_KERNEL_B_CONTINUE;
853 try_kernel_lversion[0] = kernelB_lversion;
854 try_kernel[1] = kernelA;
855 try_kernel_which[1] = BOOT_KERNEL_A_CONTINUE;
856 try_kernel_lversion[1] = kernelA_lversion;
857 }
858
859 /* TODO(gauravsh): Changes to boot_tries_remaining and boot_priority
860 * below should be propagated to partition table. This will be added
861 * once the firmware parition table parsing code is in. */
862 for (i = 0; i < 2; i++) {
863 if ((try_kernel[i]->boot_success_flag ||
864 try_kernel[i]->boot_tries_remaining) &&
865 (VERIFY_KERNEL_SUCCESS == VerifyKernel(firmware_key_blob,
866 try_kernel[i]->kernel_blob,
867 dev_mode))) {
868 if (try_kernel[i]->boot_tries_remaining > 0)
869 try_kernel[i]->boot_tries_remaining--;
870 if (stored_lversion > try_kernel_lversion[i])
871 continue; /* Rollback: I am afraid I can't let you do that Dave. */
872 if (i == 0 && (stored_lversion < try_kernel_lversion[1])) {
873 /* The higher priority kernel is valid and bootable, See if we
874 * need to update the stored version for rollback prevention. */
875 if (VERIFY_KERNEL_SUCCESS == VerifyKernel(firmware_key_blob,
876 try_kernel[1]->kernel_blob,
877 dev_mode)) {
878 WriteStoredVersion(KERNEL_KEY_VERSION,
879 (uint16_t) (min_lversion >> 16));
880 WriteStoredVersion(KERNEL_VERSION,
881 (uint16_t) (min_lversion & 0xFFFF));
882 stored_lversion = min_lversion; /* Update stored version as it's
883 * used later. */
884 }
885 }
886 kernel_to_boot = try_kernel_which[i];
887 break; /* We found a valid kernel. */
888 }
889 try_kernel[i]->boot_priority = 0;
890 } /* for loop. */
891
892 /* Lock Kernel TPM rollback indices from further writes.
893 * TODO(gauravsh): Figure out if these can be combined into one
894 * 32-bit location since we seem to always use them together. This can help
895 * us minimize the number of NVRAM writes/locks (which are limited over flash
896 * memory lifetimes.
897 */
898 LockStoredVersion(KERNEL_KEY_VERSION);
899 LockStoredVersion(KERNEL_VERSION);
900 return kernel_to_boot;
901 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image_fw.c ('k') | src/platform/vboot_reference/utils/kernel_image_fw.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698