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 // Utility for manipulating verified boot firmware images. | 5 // Utility for manipulating verified boot firmware images. |
6 // | 6 // |
7 | 7 |
8 #include "firmware_utility.h" | 8 #include "firmware_utility.h" |
9 | 9 |
10 #include <errno.h> | |
11 #include <getopt.h> | 10 #include <getopt.h> |
12 #include <stdio.h> | 11 #include <stdio.h> |
13 #include <stdint.h> // Needed for UINT16_MAX. | 12 #include <stdint.h> // Needed for UINT16_MAX. |
14 #include <stdlib.h> | 13 #include <stdlib.h> |
15 #include <unistd.h> | 14 #include <unistd.h> |
16 | 15 |
17 #include <iostream> | 16 #include <iostream> |
18 | 17 |
19 extern "C" { | 18 extern "C" { |
20 #include "cryptolib.h" | 19 #include "cryptolib.h" |
21 #include "file_keys.h" | 20 #include "file_keys.h" |
22 #include "firmware_image.h" | 21 #include "firmware_image.h" |
23 #include "utility.h" | 22 #include "utility.h" |
24 } | 23 } |
25 | 24 |
26 extern int errno; | |
27 using std::cerr; | 25 using std::cerr; |
28 | 26 |
29 namespace vboot_reference { | 27 namespace vboot_reference { |
30 | 28 |
31 FirmwareUtility::FirmwareUtility(): | 29 FirmwareUtility::FirmwareUtility(): |
32 image_(NULL), | 30 image_(NULL), |
33 root_key_pub_(NULL), | 31 root_key_pub_(NULL), |
34 firmware_version_(-1), | 32 firmware_version_(-1), |
35 firmware_key_version_(-1), | 33 firmware_key_version_(-1), |
36 firmware_sign_algorithm_(-1), | 34 firmware_sign_algorithm_(-1), |
37 is_generate_(false), | 35 is_generate_(false), |
38 is_verify_(false), | 36 is_verify_(false), |
39 is_describe_(false), | 37 is_describe_(false), |
40 is_only_vblock_(false) { | 38 is_only_vblock_(false) { |
41 } | 39 } |
42 | 40 |
43 FirmwareUtility::~FirmwareUtility() { | 41 FirmwareUtility::~FirmwareUtility() { |
44 RSAPublicKeyFree(root_key_pub_); | 42 RSAPublicKeyFree(root_key_pub_); |
45 FirmwareImageFree(image_); | 43 FirmwareImageFree(image_); |
46 } | 44 } |
47 | 45 |
48 void FirmwareUtility::PrintUsage(void) { | 46 void FirmwareUtility::PrintUsage(void) { |
49 cerr << | 47 cerr << |
50 "Utility to generate/verify a verified boot firmware image\n\n" | 48 "Utility to generate/verify a verified boot firmware image\n" |
51 "Usage: firmware_utility <--generate|--verify> [OPTIONS]\n\n" | 49 "\n" |
| 50 "Usage: firmware_utility <--generate|--verify> [OPTIONS]\n" |
| 51 "\n" |
52 "For \"--verify\", required OPTIONS are:\n" | 52 "For \"--verify\", required OPTIONS are:\n" |
53 "--in <infile>\t\t\tVerified boot firmware image to verify.\n" | 53 "--in <infile>\t\t\tVerified boot firmware image to verify.\n" |
54 "--root_key_pub <pubkeyfile>\tPre-processed public root key " | 54 "--root_key_pub <pubkeyfile>\tPre-processed public root key " |
55 "to use for verification.\n\n" | 55 "to use for verification.\n" |
| 56 "\n" |
56 "For \"--generate\", required OPTIONS are:\n" | 57 "For \"--generate\", required OPTIONS are:\n" |
57 "--root_key <privkeyfile>\tPrivate root key file\n" | 58 "--root_key <privkeyfile>\tPrivate root key file\n" |
58 "--firmware_sign_key <privkeyfile>\tPrivate signing key file\n" | 59 "--firmware_sign_key <privkeyfile>\tPrivate signing key file\n" |
59 "--firmware_sign_key_pub <pubkeyfile>\tPre-processed public signing" | 60 "--firmware_sign_key_pub <pubkeyfile>\tPre-processed public signing" |
60 " key\n" | 61 " key\n" |
61 "--firmware_sign_algorithm <algoid>\tSigning algorithm to use\n" | 62 "--firmware_sign_algorithm <algoid>\tSigning algorithm to use\n" |
62 "--firmware_key_version <version#>\tSigning Key Version#\n" | 63 "--firmware_key_version <version#>\tSigning Key Version#\n" |
63 "--firmware_version <version#>\tFirmware Version#\n" | 64 "--firmware_version <version#>\tFirmware Version#\n" |
64 "--in <infile>\t\t\tFirmware Image to sign\n" | 65 "--in <infile>\t\t\tFirmware Image to sign\n" |
65 "--out <outfile>\t\t\tOutput file for verified boot firmware image\n\n" | 66 "--out <outfile>\t\t\tOutput file for verified boot firmware image\n" |
| 67 "\n" |
66 "Optional:\n" | 68 "Optional:\n" |
67 " --vblock\t\t\tJust output the verification block\n\n" | 69 " --vblock\t\t\tJust output the verification block\n" |
| 70 "\n" |
68 "<algoid> (for --sign-algorithm) is one of the following:\n"; | 71 "<algoid> (for --sign-algorithm) is one of the following:\n"; |
69 | |
70 for (int i = 0; i < kNumAlgorithms; i++) { | 72 for (int i = 0; i < kNumAlgorithms; i++) { |
71 cerr << i << " for " << algo_strings[i] << "\n"; | 73 cerr << i << " for " << algo_strings[i] << "\n"; |
72 } | 74 } |
73 cerr << "\n\n"; | 75 cerr << "\n\n"; |
74 } | 76 } |
75 | 77 |
76 bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { | 78 bool FirmwareUtility::ParseCmdLineOptions(int argc, char* argv[]) { |
77 int option_index; | 79 int option_index, i; |
| 80 char *e = 0; |
| 81 enum { |
| 82 OPT_ROOT_KEY = 1000, |
| 83 OPT_ROOT_KEY_PUB, |
| 84 OPT_FIRMWARE_KEY, |
| 85 OPT_FIRMWARE_KEY_PUB, |
| 86 OPT_FIRMWARE_SIGN_ALGORITHM, |
| 87 OPT_FIRMWARE_KEY_VERSION, |
| 88 OPT_FIRMWARE_VERSION, |
| 89 OPT_IN, |
| 90 OPT_OUT, |
| 91 OPT_GENERATE, |
| 92 OPT_VERIFY, |
| 93 OPT_DESCRIBE, |
| 94 OPT_VBLOCK, |
| 95 }; |
78 static struct option long_options[] = { | 96 static struct option long_options[] = { |
79 {"root_key", 1, 0, 0}, | 97 {"root_key", 1, 0, OPT_ROOT_KEY }, |
80 {"root_key_pub", 1, 0, 0}, | 98 {"root_key_pub", 1, 0, OPT_ROOT_KEY_PUB }, |
81 {"firmware_sign_key", 1, 0, 0}, | 99 {"firmware_key", 1, 0, OPT_FIRMWARE_KEY }, |
82 {"firmware_sign_key_pub", 1, 0, 0}, | 100 {"firmware_key_pub", 1, 0, OPT_FIRMWARE_KEY_PUB }, |
83 {"firmware_sign_algorithm", 1, 0, 0}, | 101 {"firmware_sign_algorithm", 1, 0, OPT_FIRMWARE_SIGN_ALGORITHM }, |
84 {"firmware_key_version", 1, 0, 0}, | 102 {"firmware_key_version", 1, 0, OPT_FIRMWARE_KEY_VERSION }, |
85 {"firmware_version", 1, 0, 0}, | 103 {"firmware_version", 1, 0, OPT_FIRMWARE_VERSION }, |
86 {"in", 1, 0, 0}, | 104 {"in", 1, 0, OPT_IN }, |
87 {"out", 1, 0, 0}, | 105 {"out", 1, 0, OPT_OUT }, |
88 {"generate", 0, 0, 0}, | 106 {"generate", 0, 0, OPT_GENERATE }, |
89 {"verify", 0, 0, 0}, | 107 {"verify", 0, 0, OPT_VERIFY }, |
90 {"describe", 0, 0, 0}, | 108 {"describe", 0, 0, OPT_DESCRIBE }, |
91 {"vblock", 0, 0, 0}, | 109 {"vblock", 0, 0, OPT_VBLOCK }, |
92 {NULL, 0, 0, 0} | 110 {NULL, 0, 0, 0} |
93 }; | 111 }; |
94 while (1) { | 112 while ((i = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { |
95 int i = getopt_long(argc, argv, "", long_options, &option_index); | 113 switch (i) { |
96 if (-1 == i) // Done with option processing. | 114 case '?': |
97 break; | 115 return false; |
98 if ('?' == i) // Invalid option found. | 116 break; |
99 return false; | 117 case OPT_ROOT_KEY: |
100 | 118 root_key_file_ = optarg; |
101 if (0 == i) { | 119 break; |
102 switch (option_index) { | 120 case OPT_ROOT_KEY_PUB: |
103 case 0: // root_key | 121 root_key_pub_file_ = optarg; |
104 root_key_file_ = optarg; | 122 break; |
105 break; | 123 case OPT_FIRMWARE_KEY: |
106 case 1: // root_key_pub | 124 firmware_key_file_ = optarg; |
107 root_key_pub_file_ = optarg; | 125 break; |
108 break; | 126 case OPT_FIRMWARE_KEY_PUB: |
109 case 2: // firmware_sign_key | 127 firmware_key_pub_file_ = optarg; |
110 firmware_key_file_ = optarg; | 128 break; |
111 break; | 129 case OPT_FIRMWARE_SIGN_ALGORITHM: |
112 case 3: // firmware_sign_key_pub | 130 firmware_sign_algorithm_ = strtol(optarg, &e, 0); |
113 firmware_key_pub_file_ = optarg; | 131 if (!*optarg || (e && *e)) { |
114 break; | 132 cerr << "Invalid argument to --" |
115 case 4: // firmware_sign_algorithm | 133 << long_options[option_index].name |
116 errno = 0; // strtol() returns an error via errno | 134 << ": " << optarg << "\n"; |
117 firmware_sign_algorithm_ = strtol(optarg, | 135 return false; |
118 reinterpret_cast<char**>(NULL), 10); | 136 } |
119 if (errno) | 137 break; |
120 return false; | 138 case OPT_FIRMWARE_KEY_VERSION: |
121 break; | 139 firmware_key_version_ = strtol(optarg, &e, 0); |
122 case 5: // firmware_key_version | 140 if (!*optarg || (e && *e)) { |
123 errno = 0; | 141 cerr << "Invalid argument to --" |
124 firmware_key_version_ = strtol(optarg, | 142 << long_options[option_index].name |
125 reinterpret_cast<char**>(NULL), 10); | 143 << ": " << optarg << "\n"; |
126 if (errno) | 144 return false; |
127 return false; | 145 } |
128 break; | 146 break; |
129 case 6: // firmware_version | 147 case OPT_FIRMWARE_VERSION: |
130 errno = 0; | 148 firmware_version_ = strtol(optarg, &e, 0); |
131 firmware_version_ = strtol(optarg, | 149 if (!*optarg || (e && *e)) { |
132 reinterpret_cast<char**>(NULL), 10); | 150 cerr << "Invalid argument to --" |
133 if (errno) | 151 << long_options[option_index].name |
134 return false; | 152 << ": " << optarg << "\n"; |
135 break; | 153 return false; |
136 case 7: // in | 154 } |
137 in_file_ = optarg; | 155 break; |
138 break; | 156 case OPT_IN: |
139 case 8: // out | 157 in_file_ = optarg; |
140 out_file_ = optarg; | 158 break; |
141 break; | 159 case OPT_OUT: |
142 case 9: // generate | 160 out_file_ = optarg; |
143 is_generate_ = true; | 161 break; |
144 break; | 162 case OPT_GENERATE: |
145 case 10: // verify | 163 is_generate_ = true; |
| 164 break; |
| 165 case OPT_VERIFY: |
146 is_verify_ = true; | 166 is_verify_ = true; |
147 break; | 167 break; |
148 case 11: // describe | 168 case OPT_DESCRIBE: |
149 is_describe_ = true; | 169 is_describe_ = true; |
150 break; | 170 break; |
151 case 12: // vblock | 171 case OPT_VBLOCK: |
152 is_only_vblock_ = true; | 172 is_only_vblock_ = true; |
153 break; | 173 break; |
154 } | |
155 } | 174 } |
156 } | 175 } |
157 return CheckOptions(); | 176 return CheckOptions(); |
158 } | 177 } |
159 | 178 |
160 | 179 |
161 void FirmwareUtility::OutputSignedImage(void) { | 180 void FirmwareUtility::OutputSignedImage(void) { |
162 if (image_) { | 181 if (image_) { |
163 if (!WriteFirmwareImage(out_file_.c_str(), image_, is_only_vblock_)) { | 182 if (!WriteFirmwareImage(out_file_.c_str(), image_, is_only_vblock_)) { |
164 cerr << "Couldn't write verified boot image to file " | 183 cerr << "Couldn't write verified boot image to file " |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 } | 331 } |
313 if (fu.is_verify()) { | 332 if (fu.is_verify()) { |
314 cerr << "Verification "; | 333 cerr << "Verification "; |
315 if (fu.VerifySignedImage()) | 334 if (fu.VerifySignedImage()) |
316 cerr << "SUCCESS.\n"; | 335 cerr << "SUCCESS.\n"; |
317 else | 336 else |
318 cerr << "FAILURE.\n"; | 337 cerr << "FAILURE.\n"; |
319 } | 338 } |
320 return 0; | 339 return 0; |
321 } | 340 } |
OLD | NEW |