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> | 10 #include <errno.h> |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 namespace vboot_reference { | 31 namespace vboot_reference { |
32 | 32 |
33 FirmwareUtility::FirmwareUtility(): | 33 FirmwareUtility::FirmwareUtility(): |
34 image_(NULL), | 34 image_(NULL), |
35 root_key_pub_(NULL), | 35 root_key_pub_(NULL), |
36 firmware_version_(-1), | 36 firmware_version_(-1), |
37 firmware_key_version_(-1), | 37 firmware_key_version_(-1), |
38 firmware_sign_algorithm_(-1), | 38 firmware_sign_algorithm_(-1), |
39 is_generate_(false), | 39 is_generate_(false), |
40 is_verify_(false) { | 40 is_verify_(false), |
| 41 is_describe_(false) { |
41 } | 42 } |
42 | 43 |
43 FirmwareUtility::~FirmwareUtility() { | 44 FirmwareUtility::~FirmwareUtility() { |
44 RSAPublicKeyFree(root_key_pub_); | 45 RSAPublicKeyFree(root_key_pub_); |
45 FirmwareImageFree(image_); | 46 FirmwareImageFree(image_); |
46 } | 47 } |
47 | 48 |
48 void FirmwareUtility::PrintUsage(void) { | 49 void FirmwareUtility::PrintUsage(void) { |
49 cerr << | 50 cerr << |
50 "Utility to generate/verify a verified boot firmware image\n\n" | 51 "Utility to generate/verify a verified boot firmware image\n\n" |
(...skipping 26 matching lines...) Expand all Loading... |
77 {"root_key_pub", 1, 0, 0}, | 78 {"root_key_pub", 1, 0, 0}, |
78 {"firmware_sign_key", 1, 0, 0}, | 79 {"firmware_sign_key", 1, 0, 0}, |
79 {"firmware_sign_key_pub", 1, 0, 0}, | 80 {"firmware_sign_key_pub", 1, 0, 0}, |
80 {"firmware_sign_algorithm", 1, 0, 0}, | 81 {"firmware_sign_algorithm", 1, 0, 0}, |
81 {"firmware_key_version", 1, 0, 0}, | 82 {"firmware_key_version", 1, 0, 0}, |
82 {"firmware_version", 1, 0, 0}, | 83 {"firmware_version", 1, 0, 0}, |
83 {"in", 1, 0, 0}, | 84 {"in", 1, 0, 0}, |
84 {"out", 1, 0, 0}, | 85 {"out", 1, 0, 0}, |
85 {"generate", 0, 0, 0}, | 86 {"generate", 0, 0, 0}, |
86 {"verify", 0, 0, 0}, | 87 {"verify", 0, 0, 0}, |
| 88 {"describe", 0, 0, 0}, |
87 {NULL, 0, 0, 0} | 89 {NULL, 0, 0, 0} |
88 }; | 90 }; |
89 while (1) { | 91 while (1) { |
90 int i = getopt_long(argc, argv, "", long_options, &option_index); | 92 int i = getopt_long(argc, argv, "", long_options, &option_index); |
91 if (-1 == i) // Done with option processing. | 93 if (-1 == i) // Done with option processing. |
92 break; | 94 break; |
93 if ('?' == i) // Invalid option found. | 95 if ('?' == i) // Invalid option found. |
94 return false; | 96 return false; |
95 | 97 |
96 if (0 == i) { | 98 if (0 == i) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 break; | 132 break; |
131 case 7: // in | 133 case 7: // in |
132 in_file_ = optarg; | 134 in_file_ = optarg; |
133 break; | 135 break; |
134 case 8: // out | 136 case 8: // out |
135 out_file_ = optarg; | 137 out_file_ = optarg; |
136 break; | 138 break; |
137 case 9: // generate | 139 case 9: // generate |
138 is_generate_ = true; | 140 is_generate_ = true; |
139 break; | 141 break; |
140 case 10: // verify | 142 case 10: // verify |
141 is_verify_ = true; | 143 is_verify_ = true; |
142 break; | 144 break; |
| 145 case 11: // describe |
| 146 is_describe_ = true; |
| 147 break; |
143 } | 148 } |
144 } | 149 } |
145 } | 150 } |
146 return CheckOptions(); | 151 return CheckOptions(); |
147 } | 152 } |
148 | 153 |
149 | 154 |
150 void FirmwareUtility::OutputSignedImage(void) { | 155 void FirmwareUtility::OutputSignedImage(void) { |
151 if (image_) { | 156 if (image_) { |
152 if (!WriteFirmwareImage(out_file_.c_str(), image_)) { | 157 if (!WriteFirmwareImage(out_file_.c_str(), image_)) { |
153 cerr << "Couldn't write verified boot image to file " | 158 cerr << "Couldn't write verified boot image to file " |
154 << out_file_ <<".\n"; | 159 << out_file_ <<".\n"; |
155 } | 160 } |
156 } | 161 } |
157 } | 162 } |
158 | 163 |
| 164 void FirmwareUtility::DescribeSignedImage(void) { |
| 165 image_ = ReadFirmwareImage(in_file_.c_str()); |
| 166 if (!image_) { |
| 167 cerr << "Couldn't read firmware image or malformed image.\n"; |
| 168 } |
| 169 PrintFirmwareImage(image_); |
| 170 } |
| 171 |
159 bool FirmwareUtility::GenerateSignedImage(void) { | 172 bool FirmwareUtility::GenerateSignedImage(void) { |
160 uint64_t firmware_sign_key_pub_len; | 173 uint64_t firmware_sign_key_pub_len; |
161 uint8_t* header_checksum; | |
162 DigestContext ctx; | |
163 image_ = FirmwareImageNew(); | 174 image_ = FirmwareImageNew(); |
164 | 175 |
165 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); | 176 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); |
166 | 177 |
167 // Copy pre-processed public signing key. | 178 // Copy pre-processed public signing key. |
168 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; | 179 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; |
169 image_->firmware_sign_key = BufferFromFile( | 180 image_->firmware_sign_key = BufferFromFile( |
170 firmware_key_pub_file_.c_str(), | 181 firmware_key_pub_file_.c_str(), |
171 &firmware_sign_key_pub_len); | 182 &firmware_sign_key_pub_len); |
172 if (!image_->firmware_sign_key) | 183 if (!image_->firmware_sign_key) |
173 return false; | 184 return false; |
174 image_->firmware_key_version = firmware_key_version_; | 185 image_->firmware_key_version = firmware_key_version_; |
175 | 186 |
176 // Update header length. | 187 // Update header length. |
177 image_->header_len = GetFirmwareHeaderLen(image_); | 188 image_->header_len = GetFirmwareHeaderLen(image_); |
178 | 189 |
179 // Calculate header checksum. | 190 // Calculate header checksum. |
180 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); | 191 CalculateFirmwareHeaderChecksum(image_, image_->header_checksum); |
181 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->header_len), | |
182 sizeof(image_->header_len)); | |
183 DigestUpdate(&ctx, | |
184 reinterpret_cast<uint8_t*>(&image_->firmware_sign_algorithm), | |
185 sizeof(image_->firmware_sign_algorithm)); | |
186 DigestUpdate(&ctx, image_->firmware_sign_key, | |
187 RSAProcessedKeySize(image_->firmware_sign_algorithm)); | |
188 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->firmware_key_version), | |
189 sizeof(image_->firmware_key_version)); | |
190 header_checksum = DigestFinal(&ctx); | |
191 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); | |
192 Free(header_checksum); | |
193 | 192 |
194 image_->firmware_version = firmware_version_; | 193 image_->firmware_version = firmware_version_; |
195 image_->firmware_len = 0; | 194 image_->firmware_len = 0; |
196 // TODO(gauravsh): Populate this with the right bytes once we decide | 195 // TODO(gauravsh): Populate this with the right bytes once we decide |
197 // what goes into the preamble. | 196 // what goes into the preamble. |
198 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); | 197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); |
199 image_->firmware_data = BufferFromFile(in_file_.c_str(), | 198 image_->firmware_data = BufferFromFile(in_file_.c_str(), |
200 &image_->firmware_len); | 199 &image_->firmware_len); |
201 if (!image_) | 200 if (!image_) |
202 return false; | 201 return false; |
(...skipping 25 matching lines...) Expand all Loading... |
228 return false; | 227 return false; |
229 } | 228 } |
230 if (!(error = VerifyFirmwareImage(root_key_pub_, image_, | 229 if (!(error = VerifyFirmwareImage(root_key_pub_, image_, |
231 0))) // Trusted Mode. | 230 0))) // Trusted Mode. |
232 return true; | 231 return true; |
233 cerr << VerifyFirmwareErrorString(error) << "\n"; | 232 cerr << VerifyFirmwareErrorString(error) << "\n"; |
234 return false;; | 233 return false;; |
235 } | 234 } |
236 | 235 |
237 bool FirmwareUtility::CheckOptions(void) { | 236 bool FirmwareUtility::CheckOptions(void) { |
238 if (is_generate_ == is_verify_) { | 237 // Ensure that only one of --{describe|generate|verify} is set. |
239 cerr << "One of --generate or --verify must be specified.\n"; | 238 if (!((is_describe_ && !is_generate_ && !is_verify_) || |
| 239 (!is_describe_ && is_generate_ && !is_verify_) || |
| 240 (!is_describe_ && !is_generate_ && is_verify_))) { |
| 241 cerr << "One (and only one) of --describe, --generate or --verify " |
| 242 << "must be specified.\n"; |
240 return false; | 243 return false; |
241 } | 244 } |
242 // Common required options. | 245 // Common required options. |
243 if (in_file_.empty()) { | 246 if (in_file_.empty()) { |
244 cerr << "No input file specified." << "\n"; | 247 cerr << "No input file specified." << "\n"; |
245 return false; | 248 return false; |
246 } | 249 } |
247 // Required options for --verify. | 250 // Required options for --verify. |
248 if (is_verify_ && root_key_pub_file_.empty()) { | 251 if (is_verify_ && root_key_pub_file_.empty()) { |
249 cerr << "No pre-processed public root key file specified." << "\n"; | 252 cerr << "No pre-processed public root key file specified." << "\n"; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 289 |
287 | 290 |
288 } // namespace vboot_reference | 291 } // namespace vboot_reference |
289 | 292 |
290 int main(int argc, char* argv[]) { | 293 int main(int argc, char* argv[]) { |
291 vboot_reference::FirmwareUtility fu; | 294 vboot_reference::FirmwareUtility fu; |
292 if (!fu.ParseCmdLineOptions(argc, argv)) { | 295 if (!fu.ParseCmdLineOptions(argc, argv)) { |
293 fu.PrintUsage(); | 296 fu.PrintUsage(); |
294 return -1; | 297 return -1; |
295 } | 298 } |
| 299 if (fu.is_describe()) { |
| 300 fu.DescribeSignedImage(); |
| 301 } |
296 if (fu.is_generate()) { | 302 if (fu.is_generate()) { |
297 if (!fu.GenerateSignedImage()) | 303 if (!fu.GenerateSignedImage()) |
298 return -1; | 304 return -1; |
299 fu.OutputSignedImage(); | 305 fu.OutputSignedImage(); |
300 } | 306 } |
301 if (fu.is_verify()) { | 307 if (fu.is_verify()) { |
302 cerr << "Verification "; | 308 cerr << "Verification "; |
303 if (fu.VerifySignedImage()) | 309 if (fu.VerifySignedImage()) |
304 cerr << "SUCCESS.\n"; | 310 cerr << "SUCCESS.\n"; |
305 else | 311 else |
306 cerr << "FAILURE.\n"; | 312 cerr << "FAILURE.\n"; |
307 } | 313 } |
308 return 0; | 314 return 0; |
309 } | 315 } |
OLD | NEW |