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

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

Issue 1430001: VBoot Reference: Fix splicing bugs in Firmware and Kernel verification. (Closed)
Patch Set: . Created 10 years, 9 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 */ 6 */
7 7
8 #include "kernel_image.h" 8 #include "kernel_image.h"
9 9
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 RSAProcessedKeySize(image->kernel_sign_algorithm)); 213 RSAProcessedKeySize(image->kernel_sign_algorithm));
214 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); 214 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
215 215
216 if (st.remaining_len != 0) { /* Underrun or Overrun. */ 216 if (st.remaining_len != 0) { /* Underrun or Overrun. */
217 Free(header_blob); 217 Free(header_blob);
218 return NULL; 218 return NULL;
219 } 219 }
220 return header_blob; 220 return header_blob;
221 } 221 }
222 222
223 int GetKernelConfigLen(const KernelImage* image) { 223 int GetKernelConfigLen() {
224 return (FIELD_LEN(kernel_version) + 224 return (FIELD_LEN(kernel_version) +
225 FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) + 225 FIELD_LEN(options.version) + FIELD_LEN(options.cmd_line) +
226 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) + 226 FIELD_LEN(options.kernel_len) + FIELD_LEN(options.kernel_load_addr) +
227 FIELD_LEN(options.kernel_entry_addr)); 227 FIELD_LEN(options.kernel_entry_addr));
228 } 228 }
229 229
230 uint8_t* GetKernelConfigBlob(const KernelImage* image) { 230 uint8_t* GetKernelConfigBlob(const KernelImage* image) {
231 uint8_t* config_blob = NULL; 231 uint8_t* config_blob = NULL;
232 MemcpyState st; 232 MemcpyState st;
233 233
234 config_blob = (uint8_t*) Malloc(GetKernelConfigLen(image)); 234 config_blob = (uint8_t*) Malloc(GetKernelConfigLen());
235 st.remaining_len = GetKernelConfigLen(image); 235 st.remaining_len = GetKernelConfigLen();
236 st.remaining_buf = config_blob; 236 st.remaining_buf = config_blob;
237 237
238 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version)); 238 StatefulMemcpy_r(&st, &image->kernel_version, FIELD_LEN(kernel_version));
239 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version)); 239 StatefulMemcpy_r(&st, image->options.version, FIELD_LEN(options.version));
240 StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line)); 240 StatefulMemcpy_r(&st, image->options.cmd_line, FIELD_LEN(options.cmd_line));
241 StatefulMemcpy_r(&st, &image->options.kernel_len, 241 StatefulMemcpy_r(&st, &image->options.kernel_len,
242 FIELD_LEN(options.kernel_len)); 242 FIELD_LEN(options.kernel_len));
243 StatefulMemcpy_r(&st, &image->options.kernel_load_addr, 243 StatefulMemcpy_r(&st, &image->options.kernel_load_addr,
244 FIELD_LEN(options.kernel_load_addr)); 244 FIELD_LEN(options.kernel_load_addr));
245 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr, 245 StatefulMemcpy_r(&st, &image->options.kernel_entry_addr,
(...skipping 13 matching lines...) Expand all
259 uint8_t* config_blob = NULL; 259 uint8_t* config_blob = NULL;
260 MemcpyState st; 260 MemcpyState st;
261 261
262 if (!image) 262 if (!image)
263 return NULL; 263 return NULL;
264 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm]; 264 kernel_key_signature_len = siglen_map[image->firmware_sign_algorithm];
265 kernel_signature_len = siglen_map[image->kernel_sign_algorithm]; 265 kernel_signature_len = siglen_map[image->kernel_sign_algorithm];
266 *blob_len = (FIELD_LEN(magic) + 266 *blob_len = (FIELD_LEN(magic) +
267 GetKernelHeaderLen(image) + 267 GetKernelHeaderLen(image) +
268 kernel_key_signature_len + 268 kernel_key_signature_len +
269 GetKernelConfigLen(image) + 269 GetKernelConfigLen() +
270 2 * kernel_signature_len + 270 2 * kernel_signature_len +
271 image->options.kernel_len); 271 image->options.kernel_len);
272 kernel_blob = (uint8_t*) Malloc(*blob_len); 272 kernel_blob = (uint8_t*) Malloc(*blob_len);
273 st.remaining_len = *blob_len; 273 st.remaining_len = *blob_len;
274 st.remaining_buf = kernel_blob; 274 st.remaining_buf = kernel_blob;
275 275
276 header_blob = GetKernelHeaderBlob(image); 276 header_blob = GetKernelHeaderBlob(image);
277 config_blob = GetKernelConfigBlob(image); 277 config_blob = GetKernelConfigBlob(image);
278 278
279 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); 279 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
280 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image)); 280 StatefulMemcpy_r(&st, header_blob, GetKernelHeaderLen(image));
281 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len); 281 StatefulMemcpy_r(&st, image->kernel_key_signature, kernel_key_signature_len);
282 StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen(image)); 282 StatefulMemcpy_r(&st, config_blob, GetKernelConfigLen());
283 StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len); 283 StatefulMemcpy_r(&st, image->config_signature, kernel_signature_len);
284 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len); 284 StatefulMemcpy_r(&st, image->kernel_signature, kernel_signature_len);
285 StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len); 285 StatefulMemcpy_r(&st, image->kernel_data, image->options.kernel_len);
286 286
287 Free(config_blob); 287 Free(config_blob);
288 Free(header_blob); 288 Free(header_blob);
289 289
290 if (st.remaining_len != 0) { /* Underrun or Overrun. */ 290 if (st.remaining_len != 0) { /* Underrun or Overrun. */
291 Free(kernel_blob); 291 Free(kernel_blob);
292 return NULL; 292 return NULL;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; 446 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
447 } 447 }
448 return 0; 448 return 0;
449 } 449 }
450 450
451 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 451 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key,
452 const uint8_t* config_blob, 452 const uint8_t* config_blob,
453 int algorithm, 453 int algorithm,
454 int* kernel_len) { 454 int* kernel_len) {
455 uint32_t len, config_len; 455 uint32_t len, config_len;
456 config_len = GetKernelConfigLen(NULL); 456 config_len = GetKernelConfigLen();
457 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ 457 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */
458 config_blob, /* Data to verify */ 458 config_blob, /* Data to verify */
459 config_len, /* Length of data */ 459 config_len, /* Length of data */
460 config_blob + config_len, /* Expected Signature */ 460 config_blob + config_len, /* Expected Signature */
461 algorithm)) 461 algorithm))
462 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; 462 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
463 463
464 Memcpy(&len, 464 Memcpy(&len,
465 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + 465 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) +
466 FIELD_LEN(options.cmd_line)), 466 FIELD_LEN(options.cmd_line)),
467 sizeof(len)); 467 sizeof(len));
468 *kernel_len = (int) len; 468 *kernel_len = (int) len;
469 return 0; 469 return 0;
470 } 470 }
471 471
472 int VerifyKernelData(RSAPublicKey* kernel_sign_key, 472 int VerifyKernelData(RSAPublicKey* kernel_sign_key,
473 const uint8_t* kernel_config_start,
473 const uint8_t* kernel_data_start, 474 const uint8_t* kernel_data_start,
474 int kernel_len, 475 int kernel_len,
475 int algorithm) { 476 int algorithm) {
476 int signature_len = siglen_map[algorithm]; 477 int signature_len = siglen_map[algorithm];
477 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use. */ 478 uint8_t* digest;
478 kernel_data_start + signature_len, /* Data to 479 DigestContext ctx;
479 * verify */ 480
480 kernel_len, /* Length of data. */ 481 /* Since the kernel signature is computed over the kernel version, options
481 kernel_data_start, /* Expected Signature */ 482 * and data, which does not form a contiguous region of memory, we calculate
482 algorithm)) 483 * the message digest ourselves. */
484 DigestInit(&ctx, algorithm);
485 DigestUpdate(&ctx, kernel_config_start, GetKernelConfigLen());
486 DigestUpdate(&ctx, kernel_data_start + signature_len, kernel_len);
487 digest = DigestFinal(&ctx);
488 if (!RSAVerifyBinaryWithDigest_f(
489 NULL, kernel_sign_key, /* Key to use. */
490 digest, /* Digest of the data to verify. */
491 kernel_data_start, /* Expected Signature */
492 algorithm)) {
493 Free(digest);
483 return VERIFY_KERNEL_SIGNATURE_FAILED; 494 return VERIFY_KERNEL_SIGNATURE_FAILED;
495 }
496 Free(digest);
484 return 0; 497 return 0;
485 } 498 }
486 499
487 int VerifyKernel(const uint8_t* firmware_key_blob, 500 int VerifyKernel(const uint8_t* firmware_key_blob,
488 const uint8_t* kernel_blob, 501 const uint8_t* kernel_blob,
489 const int dev_mode) { 502 const int dev_mode) {
490 int error_code; 503 int error_code;
491 int firmware_sign_algorithm; /* Firmware signing key algorithm. */ 504 int firmware_sign_algorithm; /* Firmware signing key algorithm. */
492 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */ 505 int kernel_sign_algorithm; /* Kernel Signing key algorithm. */
493 RSAPublicKey* kernel_sign_key; 506 RSAPublicKey* kernel_sign_key;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 /* Only continue if config verification succeeds. */ 542 /* Only continue if config verification succeeds. */
530 config_ptr = (header_ptr + header_len + kernel_key_signature_len); 543 config_ptr = (header_ptr + header_len + kernel_key_signature_len);
531 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr, 544 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr,
532 kernel_sign_algorithm, 545 kernel_sign_algorithm,
533 &kernel_len))) { 546 &kernel_len))) {
534 RSAPublicKeyFree(kernel_sign_key); 547 RSAPublicKeyFree(kernel_sign_key);
535 return error_code; /* AKA jump to recovery. */ 548 return error_code; /* AKA jump to recovery. */
536 } 549 }
537 /* Only continue if kernel data verification succeeds. */ 550 /* Only continue if kernel data verification succeeds. */
538 kernel_ptr = (config_ptr + 551 kernel_ptr = (config_ptr +
539 GetKernelConfigLen(NULL) + /* Skip config block/signature. */ 552 GetKernelConfigLen() + /* Skip config block/signature. */
540 kernel_signature_len); 553 kernel_signature_len);
541 554
542 if ((error_code = VerifyKernelData(kernel_sign_key, kernel_ptr, kernel_len, 555 if ((error_code = VerifyKernelData(kernel_sign_key, config_ptr, kernel_ptr,
556 kernel_len,
543 kernel_sign_algorithm))) { 557 kernel_sign_algorithm))) {
544 RSAPublicKeyFree(kernel_sign_key); 558 RSAPublicKeyFree(kernel_sign_key);
545 return error_code; /* AKA jump to recovery. */ 559 return error_code; /* AKA jump to recovery. */
546 } 560 }
547 RSAPublicKeyFree(kernel_sign_key); 561 RSAPublicKeyFree(kernel_sign_key);
548 return 0; /* Success! */ 562 return 0; /* Success! */
549 } 563 }
550 564
551 int VerifyKernelImage(const RSAPublicKey* firmware_key, 565 int VerifyKernelImage(const RSAPublicKey* firmware_key,
552 const KernelImage* image, 566 const KernelImage* image,
553 const int dev_mode) { 567 const int dev_mode) {
554 RSAPublicKey* kernel_sign_key = NULL; 568 RSAPublicKey* kernel_sign_key = NULL;
555 uint8_t* header_digest = NULL; 569 uint8_t* header_digest = NULL;
556 uint8_t* config_digest = NULL; 570 uint8_t* config_digest = NULL;
557 uint8_t* kernel_digest = NULL; 571 uint8_t* kernel_digest = NULL;
558 int kernel_sign_key_size; 572 int kernel_sign_key_size;
559 int kernel_signature_size; 573 int kernel_signature_size;
560 int error_code = 0; 574 int error_code = 0;
561 DigestContext ctx; 575 DigestContext ctx;
562 576 DigestContext kernel_ctx;
563 if (!image) 577 if (!image)
564 return VERIFY_KERNEL_INVALID_IMAGE; 578 return VERIFY_KERNEL_INVALID_IMAGE;
565 579
566 /* Verify kernel key signature on the key header if we 580 /* Verify kernel key signature on the key header if we
567 * are not in dev mode. 581 * are not in dev mode.
568 * 582 *
569 * TODO(gauravsh): Add additional sanity checks here for: 583 * TODO(gauravsh): Add additional sanity checks here for:
570 * 1) verifying the header length is correct. 584 * 1) verifying the header length is correct.
571 * 2) header_checksum is correct. 585 * 2) header_checksum is correct.
572 */ 586 */
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr, 638 DigestUpdate(&ctx, (uint8_t*) &image->options.kernel_entry_addr,
625 FIELD_LEN(options.kernel_entry_addr)); 639 FIELD_LEN(options.kernel_entry_addr));
626 config_digest = DigestFinal(&ctx); 640 config_digest = DigestFinal(&ctx);
627 if (!RSAVerify(kernel_sign_key, image->config_signature, 641 if (!RSAVerify(kernel_sign_key, image->config_signature,
628 kernel_signature_size, image->kernel_sign_algorithm, 642 kernel_signature_size, image->kernel_sign_algorithm,
629 config_digest)) { 643 config_digest)) {
630 error_code = VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; 644 error_code = VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
631 goto verify_failure; 645 goto verify_failure;
632 } 646 }
633 647
634 /* Verify firmware signature. */ 648 /* Verify kernel signature - kernel signature is computed on the contents
635 kernel_digest = DigestBuf(image->kernel_data, 649 of kernel version + kernel options + kernel_data. */
636 image->options.kernel_len, 650 DigestInit(&kernel_ctx, image->kernel_sign_algorithm);
637 image->kernel_sign_algorithm); 651 DigestUpdate(&kernel_ctx, (uint8_t*) &image->kernel_version,
652 FIELD_LEN(kernel_version));
653 DigestUpdate(&kernel_ctx, (uint8_t*) image->options.version,
654 FIELD_LEN(options.version));
655 DigestUpdate(&kernel_ctx, (uint8_t*) image->options.cmd_line,
656 FIELD_LEN(options.cmd_line));
657 DigestUpdate(&kernel_ctx, (uint8_t*) &image->options.kernel_len,
658 FIELD_LEN(options.kernel_len));
659 DigestUpdate(&kernel_ctx, (uint8_t*) &image->options.kernel_load_addr,
660 FIELD_LEN(options.kernel_load_addr));
661 DigestUpdate(&kernel_ctx, (uint8_t*) &image->options.kernel_entry_addr,
662 FIELD_LEN(options.kernel_entry_addr));
663 DigestUpdate(&kernel_ctx, image->kernel_data, image->options.kernel_len);
664 kernel_digest = DigestFinal(&kernel_ctx);
638 if (!RSAVerify(kernel_sign_key, image->kernel_signature, 665 if (!RSAVerify(kernel_sign_key, image->kernel_signature,
639 kernel_signature_size, image->kernel_sign_algorithm, 666 kernel_signature_size, image->kernel_sign_algorithm,
640 kernel_digest)) { 667 kernel_digest)) {
641 error_code = VERIFY_KERNEL_SIGNATURE_FAILED; 668 error_code = VERIFY_KERNEL_SIGNATURE_FAILED;
642 goto verify_failure; 669 goto verify_failure;
643 } 670 }
644 671
645 verify_failure: 672 verify_failure:
646 RSAPublicKeyFree(kernel_sign_key); 673 RSAPublicKeyFree(kernel_sign_key);
647 Free(kernel_digest); 674 Free(kernel_digest);
(...skipping 27 matching lines...) Expand all
675 Free(signature); 702 Free(signature);
676 Free(header_blob); 703 Free(header_blob);
677 return 1; 704 return 1;
678 } 705 }
679 706
680 int AddKernelSignature(KernelImage* image, 707 int AddKernelSignature(KernelImage* image,
681 const char* kernel_signing_key_file) { 708 const char* kernel_signing_key_file) {
682 uint8_t* config_blob = NULL; 709 uint8_t* config_blob = NULL;
683 uint8_t* config_signature = NULL; 710 uint8_t* config_signature = NULL;
684 uint8_t* kernel_signature = NULL; 711 uint8_t* kernel_signature = NULL;
712 uint8_t* kernel_buf;
685 int signature_len = siglen_map[image->kernel_sign_algorithm]; 713 int signature_len = siglen_map[image->kernel_sign_algorithm];
686 714
687 config_blob = GetKernelConfigBlob(image); 715 config_blob = GetKernelConfigBlob(image);
688 if (!(config_signature = SignatureBuf(config_blob, 716 if (!(config_signature = SignatureBuf(config_blob,
689 GetKernelConfigLen(image), 717 GetKernelConfigLen(),
690 kernel_signing_key_file, 718 kernel_signing_key_file,
691 image->kernel_sign_algorithm))) { 719 image->kernel_sign_algorithm))) {
692 fprintf(stderr, "Could not compute signature on the kernel config.\n"); 720 fprintf(stderr, "Could not compute signature on the kernel config.\n");
693 Free(config_blob); 721 Free(config_blob);
694 return 0; 722 return 0;
695 } 723 }
696 Free(config_blob);
697 724
698 image->config_signature = (uint8_t*) Malloc(signature_len); 725 image->config_signature = (uint8_t*) Malloc(signature_len);
699 Memcpy(image->config_signature, config_signature, signature_len); 726 Memcpy(image->config_signature, config_signature, signature_len);
700 Free(config_signature); 727 Free(config_signature);
701 728 /* Kernel signature muse be calculated on the kernel version, options and
702 if (!(kernel_signature = SignatureBuf(image->kernel_data, 729 * kernel data to avoid splicing attacks. */
730 kernel_buf = (uint8_t*) Malloc(GetKernelConfigLen() +
731 image->options.kernel_len);
732 Memcpy(kernel_buf, config_blob, GetKernelConfigLen());
733 Memcpy(kernel_buf + GetKernelConfigLen(), image->kernel_data,
734 image->options.kernel_len);
735 if (!(kernel_signature = SignatureBuf(kernel_buf,
736 GetKernelConfigLen() +
703 image->options.kernel_len, 737 image->options.kernel_len,
704 kernel_signing_key_file, 738 kernel_signing_key_file,
705 image->kernel_sign_algorithm))) { 739 image->kernel_sign_algorithm))) {
740 Free(config_blob);
741 Free(kernel_buf);
706 fprintf(stderr, "Could not compute signature on the kernel.\n"); 742 fprintf(stderr, "Could not compute signature on the kernel.\n");
707 return 0; 743 return 0;
708 } 744 }
709 image->kernel_signature = (uint8_t*) Malloc(signature_len); 745 image->kernel_signature = (uint8_t*) Malloc(signature_len);
710 Memcpy(image->kernel_signature, kernel_signature, signature_len); 746 Memcpy(image->kernel_signature, kernel_signature, signature_len);
711 Free(kernel_signature); 747 Free(kernel_signature);
748 Free(kernel_buf);
749 Free(config_blob);
712 return 1; 750 return 1;
713 } 751 }
714 752
715 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { 753 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) {
716 uint8_t* kernel_ptr; 754 uint8_t* kernel_ptr;
717 uint16_t kernel_key_version; 755 uint16_t kernel_key_version;
718 uint16_t kernel_version; 756 uint16_t kernel_version;
719 uint16_t firmware_sign_algorithm; 757 uint16_t firmware_sign_algorithm;
720 uint16_t kernel_sign_algorithm; 758 uint16_t kernel_sign_algorithm;
721 int kernel_key_signature_len; 759 int kernel_key_signature_len;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 /* Lock Kernel TPM rollback indices from further writes. 886 /* Lock Kernel TPM rollback indices from further writes.
849 * TODO(gauravsh): Figure out if these can be combined into one 887 * TODO(gauravsh): Figure out if these can be combined into one
850 * 32-bit location since we seem to always use them together. This can help 888 * 32-bit location since we seem to always use them together. This can help
851 * us minimize the number of NVRAM writes/locks (which are limited over flash 889 * us minimize the number of NVRAM writes/locks (which are limited over flash
852 * memory lifetimes. 890 * memory lifetimes.
853 */ 891 */
854 LockStoredVersion(KERNEL_KEY_VERSION); 892 LockStoredVersion(KERNEL_KEY_VERSION);
855 LockStoredVersion(KERNEL_VERSION); 893 LockStoredVersion(KERNEL_VERSION);
856 return kernel_to_boot; 894 return kernel_to_boot;
857 } 895 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698