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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 {NULL, 0, 0, 0} | 86 {NULL, 0, 0, 0} |
87 }; | 87 }; |
88 while (1) { | 88 while (1) { |
89 int i = getopt_long(argc, argv, "", long_options, &option_index); | 89 int i = getopt_long(argc, argv, "", long_options, &option_index); |
90 if (-1 == i) // Done with option processing. | 90 if (-1 == i) // Done with option processing. |
91 break; | 91 break; |
92 if ('?' == i) // Invalid option found. | 92 if ('?' == i) // Invalid option found. |
93 return false; | 93 return false; |
94 | 94 |
95 if (0 == i) { | 95 if (0 == i) { |
96 switch(option_index) { | 96 switch (option_index) { |
97 case 0: // root_key | 97 case 0: // root_key |
98 root_key_file_ = optarg; | 98 root_key_file_ = optarg; |
99 break; | 99 break; |
100 case 1: // root_key_pub | 100 case 1: // root_key_pub |
101 root_key_pub_file_ = optarg; | 101 root_key_pub_file_ = optarg; |
102 break; | 102 break; |
103 case 2: // firmware_sign_key | 103 case 2: // firmware_sign_key |
104 firmware_sign_key_file_ = optarg; | 104 firmware_key_file_ = optarg; |
105 break; | 105 break; |
106 case 3: // firmware_sign_key_pub | 106 case 3: // firmware_sign_key_pub |
107 firmware_sign_key_pub_file_ = optarg; | 107 firmware_key_pub_file_ = optarg; |
108 break; | 108 break; |
109 case 4: // firmware_sign_algorithm | 109 case 4: // firmware_sign_algorithm |
110 errno = 0; // strtol() returns an error via errno | 110 errno = 0; // strtol() returns an error via errno |
111 firmware_sign_algorithm_ = strtol(optarg, (char**) NULL, 10); | 111 firmware_sign_algorithm_ = strtol(optarg, |
| 112 reinterpret_cast<char**>(NULL), 10); |
112 if (errno) | 113 if (errno) |
113 return false; | 114 return false; |
114 break; | 115 break; |
115 case 5: // firmware_key_version | 116 case 5: // firmware_key_version |
116 errno = 0; | 117 errno = 0; |
117 firmware_key_version_ = strtol(optarg, (char**) NULL, 10); | 118 firmware_key_version_ = strtol(optarg, |
| 119 reinterpret_cast<char**>(NULL), 10); |
118 if (errno) | 120 if (errno) |
119 return false; | 121 return false; |
120 break; | 122 break; |
121 case 6: // firmware_version | 123 case 6: // firmware_version |
122 errno = 0; | 124 errno = 0; |
123 firmware_version_ = strtol(optarg, (char**) NULL, 10); | 125 firmware_version_ = strtol(optarg, |
| 126 reinterpret_cast<char**>(NULL), 10); |
124 if (errno) | 127 if (errno) |
125 return false; | 128 return false; |
126 break; | 129 break; |
127 case 7: // in | 130 case 7: // in |
128 in_file_ = optarg; | 131 in_file_ = optarg; |
129 break; | 132 break; |
130 case 8: // out | 133 case 8: // out |
131 out_file_ = optarg; | 134 out_file_ = optarg; |
132 break; | 135 break; |
133 case 9: // generate | 136 case 9: // generate |
(...skipping 22 matching lines...) Expand all Loading... |
156 uint32_t firmware_sign_key_pub_len; | 159 uint32_t firmware_sign_key_pub_len; |
157 uint8_t* header_checksum; | 160 uint8_t* header_checksum; |
158 DigestContext ctx; | 161 DigestContext ctx; |
159 image_ = FirmwareImageNew(); | 162 image_ = FirmwareImageNew(); |
160 | 163 |
161 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); | 164 Memcpy(image_->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE); |
162 | 165 |
163 // Copy pre-processed public signing key. | 166 // Copy pre-processed public signing key. |
164 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; | 167 image_->firmware_sign_algorithm = (uint16_t) firmware_sign_algorithm_; |
165 image_->firmware_sign_key = BufferFromFile( | 168 image_->firmware_sign_key = BufferFromFile( |
166 firmware_sign_key_pub_file_.c_str(), | 169 firmware_key_pub_file_.c_str(), |
167 &firmware_sign_key_pub_len); | 170 &firmware_sign_key_pub_len); |
168 if (!image_->firmware_sign_key) | 171 if (!image_->firmware_sign_key) |
169 return false; | 172 return false; |
170 image_->firmware_key_version = firmware_key_version_; | 173 image_->firmware_key_version = firmware_key_version_; |
171 | 174 |
172 // Update header length. | 175 // Update header length. |
173 image_->header_len = (sizeof(image_->header_len) + | 176 image_->header_len = GetFirmwareHeaderLen(image_); |
174 sizeof(image_->firmware_sign_algorithm) + | |
175 firmware_sign_key_pub_len + | |
176 sizeof(image_->firmware_key_version) + | |
177 sizeof(image_->header_checksum)); | |
178 | 177 |
179 // Calculate header checksum. | 178 // Calculate header checksum. |
180 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); | 179 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); |
181 DigestUpdate(&ctx, (uint8_t*) &image_->header_len, | 180 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->header_len), |
182 sizeof(image_->header_len)); | 181 sizeof(image_->header_len)); |
183 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_sign_algorithm, | 182 DigestUpdate(&ctx, |
| 183 reinterpret_cast<uint8_t*>(&image_->firmware_sign_algorithm), |
184 sizeof(image_->firmware_sign_algorithm)); | 184 sizeof(image_->firmware_sign_algorithm)); |
185 DigestUpdate(&ctx, image_->firmware_sign_key, | 185 DigestUpdate(&ctx, image_->firmware_sign_key, |
186 RSAProcessedKeySize(image_->firmware_sign_algorithm)); | 186 RSAProcessedKeySize(image_->firmware_sign_algorithm)); |
187 DigestUpdate(&ctx, (uint8_t*) &image_->firmware_key_version, | 187 DigestUpdate(&ctx, reinterpret_cast<uint8_t*>(&image_->firmware_key_version), |
188 sizeof(image_->firmware_key_version)); | 188 sizeof(image_->firmware_key_version)); |
189 header_checksum = DigestFinal(&ctx); | 189 header_checksum = DigestFinal(&ctx); |
190 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); | 190 Memcpy(image_->header_checksum, header_checksum, SHA512_DIGEST_SIZE); |
191 Free(header_checksum); | 191 Free(header_checksum); |
192 | 192 |
193 image_->firmware_version = firmware_version_; | 193 image_->firmware_version = firmware_version_; |
194 image_->firmware_len = 0; | 194 image_->firmware_len = 0; |
195 // TODO(gauravsh): Populate this with the right bytes once we decide | 195 // TODO(gauravsh): Populate this with the right bytes once we decide |
196 // what goes into the preamble. | 196 // what goes into the preamble. |
197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); | 197 Memset(image_->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); |
198 image_->firmware_data = BufferFromFile(in_file_.c_str(), | 198 image_->firmware_data = BufferFromFile(in_file_.c_str(), |
199 &image_->firmware_len); | 199 &image_->firmware_len); |
200 if (!image_) | 200 if (!image_) |
201 return false; | 201 return false; |
202 // Generate and add the signatures. | 202 // Generate and add the signatures. |
203 if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { | 203 if (!AddFirmwareKeySignature(image_, root_key_file_.c_str())) { |
204 cerr << "Couldn't write key signature to verified boot image.\n"; | 204 cerr << "Couldn't write key signature to verified boot image.\n"; |
205 return false; | 205 return false; |
206 } | 206 } |
207 | 207 |
208 if (!AddFirmwareSignature(image_, firmware_sign_key_file_.c_str())) { | 208 if (!AddFirmwareSignature(image_, firmware_key_file_.c_str())) { |
209 cerr << "Couldn't write firmware signature to verified boot image.\n"; | 209 cerr << "Couldn't write firmware signature to verified boot image.\n"; |
210 return false; | 210 return false; |
211 } | 211 } |
212 return true; | 212 return true; |
213 } | 213 } |
214 | 214 |
215 bool FirmwareUtility::VerifySignedImage(void) { | 215 bool FirmwareUtility::VerifySignedImage(void) { |
216 int error; | 216 int error; |
217 root_key_pub_ = RSAPublicKeyFromFile(root_key_pub_file_.c_str()); | 217 root_key_pub_ = RSAPublicKeyFromFile(root_key_pub_file_.c_str()); |
218 image_ = ReadFirmwareImage(in_file_.c_str()); | 218 image_ = ReadFirmwareImage(in_file_.c_str()); |
219 | 219 |
220 if (!root_key_pub_) { | 220 if (!root_key_pub_) { |
221 cerr << "Couldn't read pre-processed public root key.\n"; | 221 cerr << "Couldn't read pre-processed public root key.\n"; |
222 return false; | 222 return false; |
223 } | 223 } |
224 | 224 |
225 if (!image_) { | 225 if (!image_) { |
226 cerr << "Couldn't read firmware image or malformed image.\n"; | 226 cerr << "Couldn't read firmware image or malformed image.\n"; |
227 return false; | 227 return false; |
228 } | 228 } |
229 if(!(error = VerifyFirmwareImage(root_key_pub_, image_, 0))) // Trusted Mode. | 229 if (!(error = VerifyFirmwareImage(root_key_pub_, image_, |
| 230 0))) // Trusted Mode. |
230 return true; | 231 return true; |
231 cerr << VerifyFirmwareErrorString(error) << "\n"; | 232 cerr << VerifyFirmwareErrorString(error) << "\n"; |
232 return false;; | 233 return false;; |
233 } | 234 } |
234 | 235 |
235 bool FirmwareUtility::CheckOptions(void) { | 236 bool FirmwareUtility::CheckOptions(void) { |
236 if (is_generate_ == is_verify_) { | 237 if (is_generate_ == is_verify_) { |
237 cerr << "One of --generate or --verify must be specified.\n"; | 238 cerr << "One of --generate or --verify must be specified.\n"; |
238 return false; | 239 return false; |
239 } | 240 } |
(...skipping 10 matching lines...) Expand all Loading... |
250 // Required options for --generate. | 251 // Required options for --generate. |
251 if (is_generate_) { | 252 if (is_generate_) { |
252 if (root_key_file_.empty()) { | 253 if (root_key_file_.empty()) { |
253 cerr << "No root key file specified." << "\n"; | 254 cerr << "No root key file specified." << "\n"; |
254 return false; | 255 return false; |
255 } | 256 } |
256 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) { | 257 if (firmware_version_ <= 0 || firmware_version_ > UINT16_MAX) { |
257 cerr << "Invalid or no firmware version specified." << "\n"; | 258 cerr << "Invalid or no firmware version specified." << "\n"; |
258 return false; | 259 return false; |
259 } | 260 } |
260 if (firmware_sign_key_file_.empty()) { | 261 if (firmware_key_file_.empty()) { |
261 cerr << "No signing key file specified." << "\n"; | 262 cerr << "No signing key file specified." << "\n"; |
262 return false; | 263 return false; |
263 } | 264 } |
264 if (firmware_sign_key_pub_file_.empty()) { | 265 if (firmware_key_pub_file_.empty()) { |
265 cerr << "No pre-processed public signing key file specified." << "\n"; | 266 cerr << "No pre-processed public signing key file specified." << "\n"; |
266 return false; | 267 return false; |
267 } | 268 } |
268 if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) { | 269 if (firmware_key_version_ <= 0 || firmware_key_version_ > UINT16_MAX) { |
269 cerr << "Invalid or no key version specified." << "\n"; | 270 cerr << "Invalid or no key version specified." << "\n"; |
270 return false; | 271 return false; |
271 } | 272 } |
272 if (firmware_sign_algorithm_ < 0 || | 273 if (firmware_sign_algorithm_ < 0 || |
273 firmware_sign_algorithm_ >= kNumAlgorithms) { | 274 firmware_sign_algorithm_ >= kNumAlgorithms) { |
274 cerr << "Invalid or no signing key algorithm specified." << "\n"; | 275 cerr << "Invalid or no signing key algorithm specified." << "\n"; |
(...skipping 16 matching lines...) Expand all Loading... |
291 fu.PrintUsage(); | 292 fu.PrintUsage(); |
292 return -1; | 293 return -1; |
293 } | 294 } |
294 if (fu.is_generate()) { | 295 if (fu.is_generate()) { |
295 if (!fu.GenerateSignedImage()) | 296 if (!fu.GenerateSignedImage()) |
296 return -1; | 297 return -1; |
297 fu.OutputSignedImage(); | 298 fu.OutputSignedImage(); |
298 } | 299 } |
299 if (fu.is_verify()) { | 300 if (fu.is_verify()) { |
300 cerr << "Verification "; | 301 cerr << "Verification "; |
301 if(fu.VerifySignedImage()) | 302 if (fu.VerifySignedImage()) |
302 cerr << "SUCCESS.\n"; | 303 cerr << "SUCCESS.\n"; |
303 else | 304 else |
304 cerr << "FAILURE.\n"; | 305 cerr << "FAILURE.\n"; |
305 } | 306 } |
306 return 0; | 307 return 0; |
307 } | 308 } |
OLD | NEW |