| OLD | NEW |
| 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 * Verified boot kernel utility | 5 * Verified boot kernel utility |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <getopt.h> | 9 #include <getopt.h> |
| 10 #include <inttypes.h> /* For PRIu64 */ | 10 #include <inttypes.h> /* For PRIu64 */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 /* Print help and return error */ | 69 /* Print help and return error */ |
| 70 static int PrintHelp(char *progname) { | 70 static int PrintHelp(char *progname) { |
| 71 fprintf(stderr, | 71 fprintf(stderr, |
| 72 "This program creates, signs, and verifies the kernel blob\n"); | 72 "This program creates, signs, and verifies the kernel blob\n"); |
| 73 fprintf(stderr, | 73 fprintf(stderr, |
| 74 "\n" | 74 "\n" |
| 75 "Usage: %s --pack <file> [PARAMETERS]\n" | 75 "Usage: %s --pack <file> [PARAMETERS]\n" |
| 76 "\n" | 76 "\n" |
| 77 " Required parameters:\n" | 77 " Required parameters:\n" |
| 78 " --keyblock <file> Key block in .keyblock format\n" | 78 " --keyblock <file> Key block in .keyblock format\n" |
| 79 " --signprivate <file> Signing private key in .pem format\n" | 79 " --signprivate <file>" |
| 80 " Private key to sign kernel data, in .vbprivk format\n" |
| 80 " --version <number> Kernel version\n" | 81 " --version <number> Kernel version\n" |
| 81 " --vmlinuz <file> Linux kernel bzImage file\n" | 82 " --vmlinuz <file> Linux kernel bzImage file\n" |
| 82 " --bootloader <file> Bootloader stub\n" | 83 " --bootloader <file> Bootloader stub\n" |
| 83 " --config <file> Command line file\n" | 84 " --config <file> Command line file\n" |
| 84 "\n" | 85 "\n" |
| 85 " Optional:\n" | 86 " Optional:\n" |
| 86 " --pad <number> Verification padding size in bytes\n" | 87 " --pad <number> Verification padding size in bytes\n" |
| 87 " --vblockonly Emit just the verification blob\n", | 88 " --vblockonly Emit just the verification blob\n", |
| 88 progname); | 89 progname); |
| 89 fprintf(stderr, | 90 fprintf(stderr, |
| 90 "\nOR\n\n" | 91 "\nOR\n\n" |
| 91 "Usage: %s --repack <file> [PARAMETERS]\n" | 92 "Usage: %s --repack <file> [PARAMETERS]\n" |
| 92 "\n" | 93 "\n" |
| 93 " Required parameters (of --keyblock and --config at least " | 94 " Required parameters (of --keyblock and --config at least " |
| 94 "one is required):\n" | 95 "one is required):\n" |
| 95 " --keyblock <file> Key block in .keyblock format\n" | 96 " --keyblock <file> Key block in .keyblock format\n" |
| 96 " --signprivate <file> Signing private key in .pem format\n" | 97 " --signprivate <file>" |
| 98 " Private key to sign kernel data, in .vbprivk format\n" |
| 97 " --oldblob <file> Previously packed kernel blob\n" | 99 " --oldblob <file> Previously packed kernel blob\n" |
| 98 " --config <file> New command line file\n" | 100 " --config <file> New command line file\n" |
| 99 "\n" | 101 "\n" |
| 100 " Optional:\n" | 102 " Optional:\n" |
| 101 " --pad <number> Verification padding size in bytes\n" | 103 " --pad <number> Verification padding size in bytes\n" |
| 102 " --vblockonly Emit just the verification blob\n", | 104 " --vblockonly Emit just the verification blob\n", |
| 103 progname); | 105 progname); |
| 104 fprintf(stderr, | 106 fprintf(stderr, |
| 105 "\nOR\n\n" | 107 "\nOR\n\n" |
| 106 "Usage: %s --verify <file> [PARAMETERS]\n" | 108 "Usage: %s --verify <file> [PARAMETERS]\n" |
| 107 "\n" | 109 "\n" |
| 108 " Required parameters:\n" | |
| 109 " --signpubkey <file> Signing public key in .vbpubk format\n" | |
| 110 "\n" | |
| 111 " Optional:\n" | 110 " Optional:\n" |
| 111 " --signpubkey <file>" |
| 112 " Public key to verify kernel keyblock, in .vbpubk format\n" |
| 112 " --verbose Print a more detailed report\n" | 113 " --verbose Print a more detailed report\n" |
| 113 "\n", | 114 "\n", |
| 114 progname); | 115 progname); |
| 115 return 1; | 116 return 1; |
| 116 } | 117 } |
| 117 | 118 |
| 118 static void Debug(const char *format, ...) { | 119 static void Debug(const char *format, ...) { |
| 119 if (!opt_debug) | 120 if (!opt_debug) |
| 120 return; | 121 return; |
| 121 | 122 |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 Memcpy(BpCmdLineLocation(bp), new_conf, config_size); | 605 Memcpy(BpCmdLineLocation(bp), new_conf, config_size); |
| 605 Free(new_conf); | 606 Free(new_conf); |
| 606 return 0; | 607 return 0; |
| 607 } | 608 } |
| 608 | 609 |
| 609 static int Verify(const char* infile, const char* signpubkey, int verbose) { | 610 static int Verify(const char* infile, const char* signpubkey, int verbose) { |
| 610 | 611 |
| 611 VbKeyBlockHeader* key_block; | 612 VbKeyBlockHeader* key_block; |
| 612 VbKernelPreambleHeader* preamble; | 613 VbKernelPreambleHeader* preamble; |
| 613 VbPublicKey* data_key; | 614 VbPublicKey* data_key; |
| 614 VbPublicKey* sign_key; | 615 VbPublicKey* sign_key = NULL; |
| 615 RSAPublicKey* rsa; | 616 RSAPublicKey* rsa; |
| 616 blob_t* bp; | 617 blob_t* bp; |
| 617 uint64_t now; | 618 uint64_t now; |
| 618 int rv = 1; | 619 int rv = 1; |
| 619 | 620 |
| 620 if (!infile || !signpubkey) { | 621 if (!infile) { |
| 621 error("Must specify filename and signpubkey\n"); | 622 error("Must specify filename\n"); |
| 622 return 1; | 623 return 1; |
| 623 } | 624 } |
| 624 | 625 |
| 625 /* Read public signing key */ | 626 /* Read public signing key */ |
| 626 sign_key = PublicKeyRead(signpubkey); | 627 if (signpubkey) { |
| 627 if (!sign_key) { | 628 sign_key = PublicKeyRead(signpubkey); |
| 628 error("Error reading signpubkey.\n"); | 629 if (!sign_key) { |
| 629 return 1; | 630 error("Error reading signpubkey.\n"); |
| 631 return 1; |
| 632 } |
| 630 } | 633 } |
| 631 | 634 |
| 632 /* Read blob */ | 635 /* Read blob */ |
| 633 bp = OldBlob(infile); | 636 bp = OldBlob(infile); |
| 634 if (!bp) { | 637 if (!bp) { |
| 635 error("Error reading input file\n"); | 638 error("Error reading input file\n"); |
| 636 return 1; | 639 return 1; |
| 637 } | 640 } |
| 638 | 641 |
| 639 /* Verify key block */ | 642 /* Verify key block */ |
| 640 key_block = bp->key_block; | 643 key_block = bp->key_block; |
| 641 if (0 != KeyBlockVerify(key_block, bp->blob_size, sign_key)) { | 644 if (0 != KeyBlockVerify(key_block, bp->blob_size, sign_key)) { |
| 642 error("Error verifying key block.\n"); | 645 error("Error verifying key block.\n"); |
| 643 goto verify_exit; | 646 goto verify_exit; |
| 644 } | 647 } |
| 645 now = key_block->key_block_size; | 648 now = key_block->key_block_size; |
| 646 | 649 |
| 647 printf("Key block:\n"); | 650 printf("Key block:\n"); |
| 648 data_key = &key_block->data_key; | 651 data_key = &key_block->data_key; |
| 652 if (verbose) |
| 653 printf(" Signature: %s\n", sign_key ? "valid" : "ignored"); |
| 649 printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size); | 654 printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size); |
| 650 printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, | 655 printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, |
| 651 (data_key->algorithm < kNumAlgorithms ? | 656 (data_key->algorithm < kNumAlgorithms ? |
| 652 algo_strings[data_key->algorithm] : "(invalid)")); | 657 algo_strings[data_key->algorithm] : "(invalid)")); |
| 653 printf(" Data key version: %" PRIu64 "\n", data_key->key_version); | 658 printf(" Data key version: %" PRIu64 "\n", data_key->key_version); |
| 654 printf(" Flags: %" PRIu64 "\n", key_block->key_block_flags); | 659 printf(" Flags: %" PRIu64 "\n", key_block->key_block_flags); |
| 655 | 660 |
| 656 rsa = PublicKeyToRSA(&key_block->data_key); | 661 rsa = PublicKeyToRSA(&key_block->data_key); |
| 657 if (!rsa) { | 662 if (!rsa) { |
| 658 error("Error parsing data key.\n"); | 663 error("Error parsing data key.\n"); |
| 659 goto verify_exit; | 664 goto verify_exit; |
| 660 } | 665 } |
| 661 | 666 |
| 662 /* Verify preamble */ | 667 /* Verify preamble */ |
| 663 preamble = bp->preamble; | 668 preamble = bp->preamble; |
| 664 if (0 != VerifyKernelPreamble( | 669 if (0 != VerifyKernelPreamble( |
| 665 preamble, bp->blob_size - key_block->key_block_size, rsa)) { | 670 preamble, bp->blob_size - key_block->key_block_size, rsa)) { |
| 666 error("Error verifying preamble.\n"); | 671 error("Error verifying preamble.\n"); |
| 667 goto verify_exit; | 672 goto verify_exit; |
| 668 } | 673 } |
| 669 now += preamble->preamble_size; | 674 now += preamble->preamble_size; |
| 670 | 675 |
| 671 printf("Preamble:\n"); | 676 printf("Preamble:\n"); |
| 672 printf(" Size: 0x%" PRIx64 "\n", preamble->preamble_size); | 677 printf(" Size: 0x%" PRIx64 "\n", preamble->preamble_size); |
| 673 printf(" Header version: %" PRIu32 ".%" PRIu32"\n", | 678 printf(" Header version: %" PRIu32 ".%" PRIu32"\n", |
| 674 preamble->header_version_major, preamble->header_version_minor); | 679 preamble->header_version_major, preamble->header_version_minor); |
| 675 printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version); | 680 printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 | 735 |
| 731 while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) && | 736 while (((i = getopt_long(argc, argv, ":", long_opts, NULL)) != -1) && |
| 732 !parse_error) { | 737 !parse_error) { |
| 733 switch (i) { | 738 switch (i) { |
| 734 default: | 739 default: |
| 735 case '?': | 740 case '?': |
| 736 /* Unhandled option */ | 741 /* Unhandled option */ |
| 737 parse_error = 1; | 742 parse_error = 1; |
| 738 break; | 743 break; |
| 739 | 744 |
| 745 case 0: |
| 746 /* silently handled option */ |
| 747 break; |
| 748 |
| 740 case OPT_MODE_PACK: | 749 case OPT_MODE_PACK: |
| 741 case OPT_MODE_REPACK: | 750 case OPT_MODE_REPACK: |
| 742 case OPT_MODE_VERIFY: | 751 case OPT_MODE_VERIFY: |
| 743 if (mode && (mode != i)) { | 752 if (mode && (mode != i)) { |
| 744 fprintf(stderr, "Only single mode can be specified\n"); | 753 fprintf(stderr, "Only single mode can be specified\n"); |
| 745 parse_error = 1; | 754 parse_error = 1; |
| 746 break; | 755 break; |
| 747 } | 756 } |
| 748 mode = i; | 757 mode = i; |
| 749 filename = optarg; | 758 filename = optarg; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 | 843 |
| 835 case OPT_MODE_VERIFY: | 844 case OPT_MODE_VERIFY: |
| 836 return Verify(filename, signpubkey, verbose); | 845 return Verify(filename, signpubkey, verbose); |
| 837 | 846 |
| 838 default: | 847 default: |
| 839 fprintf(stderr, | 848 fprintf(stderr, |
| 840 "You must specify a mode: --pack, --repack or --verify\n"); | 849 "You must specify a mode: --pack, --repack or --verify\n"); |
| 841 return PrintHelp(progname); | 850 return PrintHelp(progname); |
| 842 } | 851 } |
| 843 } | 852 } |
| OLD | NEW |