| 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 |