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 * Functions for generating and manipulating a verified boot firmware image. | 5 * Functions for generating and manipulating a verified boot firmware image. |
6 */ | 6 */ |
7 | 7 |
8 #include "firmware_image.h" | 8 #include "firmware_image.h" |
9 | 9 |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 | 74 |
75 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); | 75 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); |
76 StatefulMemcpy(&st, &image->sign_algorithm, FIELD_LEN(sign_algorithm)); | 76 StatefulMemcpy(&st, &image->sign_algorithm, FIELD_LEN(sign_algorithm)); |
77 | 77 |
78 /* Valid Algorithm? */ | 78 /* Valid Algorithm? */ |
79 if (image->sign_algorithm >= kNumAlgorithms) | 79 if (image->sign_algorithm >= kNumAlgorithms) |
80 goto parse_failure; | 80 goto parse_failure; |
81 | 81 |
82 /* Compute size of pre-processed RSA public key and signature. */ | 82 /* Compute size of pre-processed RSA public key and signature. */ |
83 sign_key_len = RSAProcessedKeySize(image->sign_algorithm); | 83 sign_key_len = RSAProcessedKeySize(image->sign_algorithm); |
84 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | 84 signature_len = siglen_map[image->sign_algorithm]; |
85 | 85 |
86 | 86 |
87 /* Check whether the header length is correct. */ | 87 /* Check whether the header length is correct. */ |
88 header_len = (FIELD_LEN(header_len) + | 88 header_len = (FIELD_LEN(header_len) + |
89 FIELD_LEN(sign_algorithm) + | 89 FIELD_LEN(sign_algorithm) + |
90 sign_key_len + | 90 sign_key_len + |
91 FIELD_LEN(key_version) + | 91 FIELD_LEN(key_version) + |
92 FIELD_LEN(header_checksum)); | 92 FIELD_LEN(header_checksum)); |
93 if (header_len != image->header_len) { | 93 if (header_len != image->header_len) { |
94 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n", | 94 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n", |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (!image) | 159 if (!image) |
160 return NULL; | 160 return NULL; |
161 if (-1 == (fd = creat(input_file, S_IRWXU))) { | 161 if (-1 == (fd = creat(input_file, S_IRWXU))) { |
162 fprintf(stderr, "Couldn't open file for writing.\n"); | 162 fprintf(stderr, "Couldn't open file for writing.\n"); |
163 return NULL; | 163 return NULL; |
164 } | 164 } |
165 | 165 |
166 write(fd, image->magic, FIELD_LEN(magic)); | 166 write(fd, image->magic, FIELD_LEN(magic)); |
167 WriteFirmwareHeader(fd, image); | 167 WriteFirmwareHeader(fd, image); |
168 write(fd, image->key_signature, FIELD_LEN(key_signature)); | 168 write(fd, image->key_signature, FIELD_LEN(key_signature)); |
169 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | 169 signature_len = siglen_map[image->sign_algorithm]; |
170 WriteFirmwarePreamble(fd, image); | 170 WriteFirmwarePreamble(fd, image); |
171 write(fd, image->preamble_signature, signature_len); | 171 write(fd, image->preamble_signature, signature_len); |
172 write(fd, image->firmware_signature, signature_len); | 172 write(fd, image->firmware_signature, signature_len); |
173 write(fd, image->firmware_data, image->firmware_len); | 173 write(fd, image->firmware_data, image->firmware_len); |
174 | 174 |
175 close(fd); | 175 close(fd); |
176 return image; | 176 return image; |
177 } | 177 } |
178 | 178 |
179 void PrintFirmwareImage(const FirmwareImage* image) { | 179 void PrintFirmwareImage(const FirmwareImage* image) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), | 286 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), |
287 sizeof(len)); | 287 sizeof(len)); |
288 *firmware_len = (int) len; | 288 *firmware_len = (int) len; |
289 return 0; | 289 return 0; |
290 } | 290 } |
291 | 291 |
292 int VerifyFirmwareData(RSAPublicKey* sign_key, | 292 int VerifyFirmwareData(RSAPublicKey* sign_key, |
293 const uint8_t* firmware_data_start, | 293 const uint8_t* firmware_data_start, |
294 int firmware_len, | 294 int firmware_len, |
295 int algorithm) { | 295 int algorithm) { |
296 int signature_len = siglen_map[algorithm] * sizeof(uint32_t); | 296 int signature_len = siglen_map[algorithm]; |
297 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use. */ | 297 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use. */ |
298 firmware_data_start + signature_len, /* Data to | 298 firmware_data_start + signature_len, /* Data to |
299 * verify */ | 299 * verify */ |
300 firmware_len, /* Length of data. */ | 300 firmware_len, /* Length of data. */ |
301 firmware_data_start, /* Expected Signature */ | 301 firmware_data_start, /* Expected Signature */ |
302 algorithm)) | 302 algorithm)) |
303 return VERIFY_FIRMWARE_SIGNATURE_FAILED; | 303 return VERIFY_FIRMWARE_SIGNATURE_FAILED; |
304 return 0; | 304 return 0; |
305 } | 305 } |
306 | 306 |
(...skipping 21 matching lines...) Expand all Loading... |
328 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode, | 328 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode, |
329 &algorithm, &header_len))) | 329 &algorithm, &header_len))) |
330 return error_code; /* AKA jump to revovery. */ | 330 return error_code; /* AKA jump to revovery. */ |
331 | 331 |
332 /* Parse signing key into RSAPublicKey structure since it is required multiple | 332 /* Parse signing key into RSAPublicKey structure since it is required multiple |
333 * times. */ | 333 * times. */ |
334 sign_key_len = RSAProcessedKeySize(algorithm); | 334 sign_key_len = RSAProcessedKeySize(algorithm); |
335 sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + | 335 sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + |
336 FIELD_LEN(sign_algorithm)); | 336 FIELD_LEN(sign_algorithm)); |
337 sign_key = RSAPublicKeyFromBuf(sign_key_ptr, sign_key_len); | 337 sign_key = RSAPublicKeyFromBuf(sign_key_ptr, sign_key_len); |
338 signature_len = siglen_map[algorithm] * sizeof(uint32_t); | 338 signature_len = siglen_map[algorithm]; |
339 | 339 |
340 /* Only continue if preamble verification succeeds. */ | 340 /* Only continue if preamble verification succeeds. */ |
341 preamble_ptr = (header_ptr + header_len + | 341 preamble_ptr = (header_ptr + header_len + |
342 FIELD_LEN(key_signature)); | 342 FIELD_LEN(key_signature)); |
343 if ((error_code = VerifyFirmwarePreamble(sign_key, preamble_ptr, algorithm, | 343 if ((error_code = VerifyFirmwarePreamble(sign_key, preamble_ptr, algorithm, |
344 &firmware_len))) | 344 &firmware_len))) |
345 return error_code; /* AKA jump to recovery. */ | 345 return error_code; /* AKA jump to recovery. */ |
346 | 346 |
347 /* Only continue if firmware data verification succeeds. */ | 347 /* Only continue if firmware data verification succeeds. */ |
348 firmware_ptr = (preamble_ptr + | 348 firmware_ptr = (preamble_ptr + |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 header_digest)) { | 399 header_digest)) { |
400 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | 400 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
401 goto verify_failure; | 401 goto verify_failure; |
402 } | 402 } |
403 } | 403 } |
404 | 404 |
405 /* Get sign key to verify the rest of the firmware. */ | 405 /* Get sign key to verify the rest of the firmware. */ |
406 sign_key_size = RSAProcessedKeySize(image->sign_algorithm); | 406 sign_key_size = RSAProcessedKeySize(image->sign_algorithm); |
407 sign_key = RSAPublicKeyFromBuf(image->sign_key, | 407 sign_key = RSAPublicKeyFromBuf(image->sign_key, |
408 sign_key_size); | 408 sign_key_size); |
409 signature_size = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | 409 signature_size = siglen_map[image->sign_algorithm]; |
410 | 410 |
411 if (image->sign_algorithm >= kNumAlgorithms) | 411 if (image->sign_algorithm >= kNumAlgorithms) |
412 return VERIFY_FIRMWARE_INVALID_ALGORITHM; | 412 return VERIFY_FIRMWARE_INVALID_ALGORITHM; |
413 | 413 |
414 /* Verify firmware preamble signature. */ | 414 /* Verify firmware preamble signature. */ |
415 DigestInit(&ctx, image->sign_algorithm); | 415 DigestInit(&ctx, image->sign_algorithm); |
416 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version, | 416 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version, |
417 FIELD_LEN(firmware_version)); | 417 FIELD_LEN(firmware_version)); |
418 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, | 418 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, |
419 FIELD_LEN(firmware_len)); | 419 FIELD_LEN(firmware_len)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 } | 470 } |
471 | 471 |
472 int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file, | 472 int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file, |
473 int algorithm) { | 473 int algorithm) { |
474 int tmp_preamble_fd; | 474 int tmp_preamble_fd; |
475 char* tmp_preamble_file = ".tmpPreambleFile"; | 475 char* tmp_preamble_file = ".tmpPreambleFile"; |
476 int tmp_firmware_fd; | 476 int tmp_firmware_fd; |
477 char* tmp_firmware_file = ".tmpFirmwareFile"; | 477 char* tmp_firmware_file = ".tmpFirmwareFile"; |
478 uint8_t* preamble_signature; | 478 uint8_t* preamble_signature; |
479 uint8_t* firmware_signature; | 479 uint8_t* firmware_signature; |
480 int signature_len = siglen_map[algorithm] * sizeof(uint32_t); | 480 int signature_len = siglen_map[algorithm]; |
481 | 481 |
482 /* Write preamble to a file. */ | 482 /* Write preamble to a file. */ |
483 if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) { | 483 if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) { |
484 fprintf(stderr, "Could not open temporary file for writing " | 484 fprintf(stderr, "Could not open temporary file for writing " |
485 "firmware preamble.\n"); | 485 "firmware preamble.\n"); |
486 return 0; | 486 return 0; |
487 } | 487 } |
488 WriteFirmwarePreamble(tmp_preamble_fd, image); | 488 WriteFirmwarePreamble(tmp_preamble_fd, image); |
489 close(tmp_preamble_fd); | 489 close(tmp_preamble_fd); |
490 if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file, | 490 if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file, |
(...skipping 15 matching lines...) Expand all Loading... |
506 algorithm))) { | 506 algorithm))) { |
507 fprintf(stderr, "Could not open temporary file for writing " | 507 fprintf(stderr, "Could not open temporary file for writing " |
508 "firmware.\n"); | 508 "firmware.\n"); |
509 return 0; | 509 return 0; |
510 } | 510 } |
511 image->firmware_signature = (uint8_t*) Malloc(signature_len); | 511 image->firmware_signature = (uint8_t*) Malloc(signature_len); |
512 Memcpy(image->firmware_signature, firmware_signature, signature_len); | 512 Memcpy(image->firmware_signature, firmware_signature, signature_len); |
513 Free(firmware_signature); | 513 Free(firmware_signature); |
514 return 1; | 514 return 1; |
515 } | 515 } |
OLD | NEW |