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 |