| 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> |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 #include <stdio.h> | 12 #include <stdio.h> |
| 13 #include <sys/types.h> | 13 #include <sys/types.h> |
| 14 #include <sys/stat.h> | 14 #include <sys/stat.h> |
| 15 #include <unistd.h> | 15 #include <unistd.h> |
| 16 | 16 |
| 17 #include "file_keys.h" | 17 #include "file_keys.h" |
| 18 #include "padding.h" | 18 #include "padding.h" |
| 19 #include "rollback_index.h" |
| 19 #include "rsa_utility.h" | 20 #include "rsa_utility.h" |
| 20 #include "sha_utility.h" | 21 #include "sha_utility.h" |
| 21 #include "signature_digest.h" | 22 #include "signature_digest.h" |
| 22 #include "utility.h" | 23 #include "utility.h" |
| 23 | 24 |
| 24 /* Macro to determine the size of a field structure in the FirmwareImage | 25 /* Macro to determine the size of a field structure in the FirmwareImage |
| 25 * structure. */ | 26 * structure. */ |
| 26 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) | 27 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) |
| 27 | 28 |
| 28 FirmwareImage* FirmwareImageNew(void) { | 29 FirmwareImage* FirmwareImageNew(void) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 /* Check whether the header length is correct. */ | 91 /* Check whether the header length is correct. */ |
| 91 header_len = GetFirmwareHeaderLen(image); | 92 header_len = GetFirmwareHeaderLen(image); |
| 92 if (header_len != image->header_len) { | 93 if (header_len != image->header_len) { |
| 93 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n", | 94 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n", |
| 94 image->header_len, header_len); | 95 image->header_len, header_len); |
| 95 Free(firmware_buf); | 96 Free(firmware_buf); |
| 96 return NULL; | 97 return NULL; |
| 97 } | 98 } |
| 98 | 99 |
| 99 /* Read pre-processed public half of the sign key. */ | 100 /* Read pre-processed public half of the sign key. */ |
| 101 StatefulMemcpy(&st, &image->firmware_key_version, |
| 102 FIELD_LEN(firmware_key_version)); |
| 100 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); | 103 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); |
| 101 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); | 104 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); |
| 102 StatefulMemcpy(&st, &image->firmware_key_version, | |
| 103 FIELD_LEN(firmware_key_version)); | |
| 104 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); | 105 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); |
| 105 | 106 |
| 106 /* Check whether the header checksum matches. */ | 107 /* Check whether the header checksum matches. */ |
| 107 CalculateFirmwareHeaderChecksum(image, header_checksum); | 108 CalculateFirmwareHeaderChecksum(image, header_checksum); |
| 108 if (SafeMemcmp(header_checksum, image->header_checksum, | 109 if (SafeMemcmp(header_checksum, image->header_checksum, |
| 109 FIELD_LEN(header_checksum))) { | 110 FIELD_LEN(header_checksum))) { |
| 110 fprintf(stderr, "Invalid firmware header checksum!\n"); | 111 fprintf(stderr, "Invalid firmware header checksum!\n"); |
| 111 Free(firmware_buf); | 112 Free(firmware_buf); |
| 112 return NULL; | 113 return NULL; |
| 113 } | 114 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 | 149 |
| 149 void CalculateFirmwareHeaderChecksum(const FirmwareImage* image, | 150 void CalculateFirmwareHeaderChecksum(const FirmwareImage* image, |
| 150 uint8_t* header_checksum) { | 151 uint8_t* header_checksum) { |
| 151 uint8_t* checksum; | 152 uint8_t* checksum; |
| 152 DigestContext ctx; | 153 DigestContext ctx; |
| 153 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); | 154 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); |
| 154 DigestUpdate(&ctx, (uint8_t*) &image->header_len, | 155 DigestUpdate(&ctx, (uint8_t*) &image->header_len, |
| 155 sizeof(image->header_len)); | 156 sizeof(image->header_len)); |
| 156 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, | 157 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, |
| 157 sizeof(image->firmware_sign_algorithm)); | 158 sizeof(image->firmware_sign_algorithm)); |
| 159 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, |
| 160 sizeof(image->firmware_key_version)); |
| 158 DigestUpdate(&ctx, image->firmware_sign_key, | 161 DigestUpdate(&ctx, image->firmware_sign_key, |
| 159 RSAProcessedKeySize(image->firmware_sign_algorithm)); | 162 RSAProcessedKeySize(image->firmware_sign_algorithm)); |
| 160 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, | |
| 161 sizeof(image->firmware_key_version)); | |
| 162 checksum = DigestFinal(&ctx); | 163 checksum = DigestFinal(&ctx); |
| 163 Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum)); | 164 Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum)); |
| 164 Free(checksum); | 165 Free(checksum); |
| 165 return; | 166 return; |
| 166 } | 167 } |
| 167 | 168 |
| 168 | 169 |
| 169 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { | 170 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { |
| 170 uint8_t* header_blob = NULL; | 171 uint8_t* header_blob = NULL; |
| 171 MemcpyState st; | 172 MemcpyState st; |
| 172 | 173 |
| 173 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); | 174 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); |
| 174 st.remaining_len = GetFirmwareHeaderLen(image); | 175 st.remaining_len = GetFirmwareHeaderLen(image); |
| 175 st.remaining_buf = header_blob; | 176 st.remaining_buf = header_blob; |
| 176 | 177 |
| 177 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); | 178 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); |
| 178 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); | 179 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); |
| 180 StatefulMemcpy_r(&st, &image->firmware_key_version, |
| 181 FIELD_LEN(firmware_key_version)); |
| 179 StatefulMemcpy_r(&st, image->firmware_sign_key, | 182 StatefulMemcpy_r(&st, image->firmware_sign_key, |
| 180 RSAProcessedKeySize(image->firmware_sign_algorithm)); | 183 RSAProcessedKeySize(image->firmware_sign_algorithm)); |
| 181 StatefulMemcpy_r(&st, &image->firmware_key_version, | |
| 182 FIELD_LEN(firmware_key_version)); | |
| 183 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); | 184 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); |
| 184 | 185 |
| 185 if (st.remaining_len != 0) { /* Underrun or Overrun. */ | 186 if (st.remaining_len != 0) { /* Underrun or Overrun. */ |
| 186 Free(header_blob); | 187 Free(header_blob); |
| 187 return NULL; | 188 return NULL; |
| 188 } | 189 } |
| 189 return header_blob; | 190 return header_blob; |
| 190 } | 191 } |
| 191 | 192 |
| 192 int GetFirmwarePreambleLen(const FirmwareImage* image) { | 193 int GetFirmwarePreambleLen(const FirmwareImage* image) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 } | 308 } |
| 308 | 309 |
| 309 char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = { | 310 char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = { |
| 310 "Success.", | 311 "Success.", |
| 311 "Invalid Image.", | 312 "Invalid Image.", |
| 312 "Root Key Signature Failed.", | 313 "Root Key Signature Failed.", |
| 313 "Invalid Verification Algorithm.", | 314 "Invalid Verification Algorithm.", |
| 314 "Preamble Signature Failed.", | 315 "Preamble Signature Failed.", |
| 315 "Firmware Signature Failed.", | 316 "Firmware Signature Failed.", |
| 316 "Wrong Firmware Magic.", | 317 "Wrong Firmware Magic.", |
| 318 "Invalid Firmware Header Checksum.", |
| 319 "Firmware Signing Key Rollback.", |
| 320 "Firmware Version Rollback." |
| 317 }; | 321 }; |
| 318 | 322 |
| 319 int VerifyFirmwareHeader(const uint8_t* root_key_blob, | 323 int VerifyFirmwareHeader(const uint8_t* root_key_blob, |
| 320 const uint8_t* header_blob, | 324 const uint8_t* header_blob, |
| 321 const int dev_mode, | 325 const int dev_mode, |
| 322 int* algorithm, | 326 int* algorithm, |
| 323 int* header_len) { | 327 int* header_len) { |
| 324 int firmware_sign_key_len; | 328 int firmware_sign_key_len; |
| 325 int root_key_len; | 329 int root_key_len; |
| 326 uint16_t hlen, algo; | 330 uint16_t hlen, algo; |
| 327 uint8_t* header_checksum = NULL; | 331 uint8_t* header_checksum = NULL; |
| 328 | 332 |
| 329 /* Base Offset for the header_checksum field. Actual offset is | 333 /* Base Offset for the header_checksum field. Actual offset is |
| 330 * this + firmware_sign_key_len. */ | 334 * this + firmware_sign_key_len. */ |
| 331 int base_header_checksum_offset = (FIELD_LEN(header_len) + | 335 int base_header_checksum_offset = (FIELD_LEN(header_len) + |
| 332 FIELD_LEN(firmware_sign_algorithm) + | 336 FIELD_LEN(firmware_sign_algorithm) + |
| 333 FIELD_LEN(firmware_key_version)); | 337 FIELD_LEN(firmware_key_version)); |
| 334 | 338 |
| 335 | 339 |
| 336 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM); | 340 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM); |
| 337 Memcpy(&hlen, header_blob, sizeof(hlen)); | 341 Memcpy(&hlen, header_blob, sizeof(hlen)); |
| 338 Memcpy(&algo, | 342 Memcpy(&algo, |
| 339 header_blob + FIELD_LEN(firmware_sign_algorithm), | 343 header_blob + FIELD_LEN(firmware_sign_algorithm), |
| 340 sizeof(algo)); | 344 sizeof(algo)); |
| 341 if (algo >= kNumAlgorithms) | 345 if (algo >= kNumAlgorithms) |
| 342 return VERIFY_FIRMWARE_INVALID_ALGORITHM; | 346 return VERIFY_FIRMWARE_INVALID_ALGORITHM; |
| 343 *algorithm = (int) algo; | 347 *algorithm = (int) algo; |
| 344 firmware_sign_key_len = RSAProcessedKeySize(*algorithm); | 348 firmware_sign_key_len = RSAProcessedKeySize(*algorithm); |
| 345 | 349 |
| 346 /* Verify if header len is correct? */ | 350 /* Verify that header len is correct. */ |
| 347 if (hlen != (base_header_checksum_offset + | 351 if (hlen != (base_header_checksum_offset + |
| 348 firmware_sign_key_len + | 352 firmware_sign_key_len + |
| 349 FIELD_LEN(header_checksum))) | 353 FIELD_LEN(header_checksum))) |
| 350 return VERIFY_FIRMWARE_INVALID_IMAGE; | 354 return VERIFY_FIRMWARE_INVALID_IMAGE; |
| 351 | 355 |
| 352 *header_len = (int) hlen; | 356 *header_len = (int) hlen; |
| 353 | 357 |
| 354 /* Verify if the hash of the header is correct. */ | 358 /* Verify if the hash of the header is correct. */ |
| 355 header_checksum = DigestBuf(header_blob, | 359 header_checksum = DigestBuf(header_blob, |
| 356 *header_len - FIELD_LEN(header_checksum), | 360 *header_len - FIELD_LEN(header_checksum), |
| 357 SHA512_DIGEST_ALGORITHM); | 361 SHA512_DIGEST_ALGORITHM); |
| 358 if (SafeMemcmp(header_checksum, | 362 if (SafeMemcmp(header_checksum, |
| 359 header_blob + (base_header_checksum_offset + | 363 header_blob + (base_header_checksum_offset + |
| 360 firmware_sign_key_len), | 364 firmware_sign_key_len), |
| 361 FIELD_LEN(header_checksum))) { | 365 FIELD_LEN(header_checksum))) { |
| 362 Free(header_checksum); | 366 Free(header_checksum); |
| 363 return VERIFY_FIRMWARE_INVALID_IMAGE; | 367 return VERIFY_FIRMWARE_WRONG_HEADER_CHECKSUM; |
| 364 } | 368 } |
| 365 Free(header_checksum); | 369 Free(header_checksum); |
| 366 | 370 |
| 367 /* Verify root key signature unless we are in dev mode. */ | 371 /* Root key signature on the firmware signing key is always checked |
| 368 if (!dev_mode) { | 372 * irrespective of dev mode. */ |
| 369 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */ | 373 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */ |
| 370 header_blob, /* Data to verify */ | 374 header_blob, /* Data to verify */ |
| 371 *header_len, /* Length of data */ | 375 *header_len, /* Length of data */ |
| 372 header_blob + *header_len, /* Expected Signature */ | 376 header_blob + *header_len, /* Expected Signature */ |
| 373 ROOT_SIGNATURE_ALGORITHM)) | 377 ROOT_SIGNATURE_ALGORITHM)) |
| 374 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | 378 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
| 375 } | |
| 376 return 0; | 379 return 0; |
| 377 } | 380 } |
| 378 | 381 |
| 379 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, | 382 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, |
| 380 const uint8_t* preamble_blob, | 383 const uint8_t* preamble_blob, |
| 381 int algorithm, | 384 int algorithm, |
| 382 int* firmware_len) { | 385 int* firmware_len) { |
| 383 uint32_t len; | 386 uint32_t len; |
| 384 int preamble_len; | 387 int preamble_len; |
| 388 uint16_t firmware_version; |
| 389 |
| 390 Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version)); |
| 391 |
| 385 preamble_len = (FIELD_LEN(firmware_version) + | 392 preamble_len = (FIELD_LEN(firmware_version) + |
| 386 FIELD_LEN(firmware_len) + | 393 FIELD_LEN(firmware_len) + |
| 387 FIELD_LEN(preamble)); | 394 FIELD_LEN(preamble)); |
| 388 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ | 395 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ |
| 389 preamble_blob, /* Data to verify */ | 396 preamble_blob, /* Data to verify */ |
| 390 preamble_len, /* Length of data */ | 397 preamble_len, /* Length of data */ |
| 391 preamble_blob + preamble_len, /* Expected Signature */ | 398 preamble_blob + preamble_len, /* Expected Signature */ |
| 392 algorithm)) | 399 algorithm)) |
| 393 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; | 400 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; |
| 394 | 401 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 442 |
| 436 /* Only continue if header verification succeeds. */ | 443 /* Only continue if header verification succeeds. */ |
| 437 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode, | 444 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode, |
| 438 &algorithm, &header_len))) | 445 &algorithm, &header_len))) |
| 439 return error_code; /* AKA jump to revovery. */ | 446 return error_code; /* AKA jump to revovery. */ |
| 440 | 447 |
| 441 /* Parse signing key into RSAPublicKey structure since it is required multiple | 448 /* Parse signing key into RSAPublicKey structure since it is required multiple |
| 442 * times. */ | 449 * times. */ |
| 443 firmware_sign_key_len = RSAProcessedKeySize(algorithm); | 450 firmware_sign_key_len = RSAProcessedKeySize(algorithm); |
| 444 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + | 451 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + |
| 445 FIELD_LEN(firmware_sign_algorithm)); | 452 FIELD_LEN(firmware_sign_algorithm) + |
| 453 FIELD_LEN(firmware_key_version)); |
| 446 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, | 454 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, |
| 447 firmware_sign_key_len); | 455 firmware_sign_key_len); |
| 448 signature_len = siglen_map[algorithm]; | 456 signature_len = siglen_map[algorithm]; |
| 449 | 457 |
| 450 /* Only continue if preamble verification succeeds. */ | 458 /* Only continue if preamble verification succeeds. */ |
| 451 preamble_ptr = (header_ptr + header_len + | 459 preamble_ptr = (header_ptr + header_len + |
| 452 FIELD_LEN(firmware_key_signature)); | 460 FIELD_LEN(firmware_key_signature)); |
| 453 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, | 461 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, |
| 454 algorithm, | 462 algorithm, |
| 455 &firmware_len))) { | 463 &firmware_len))) { |
| 456 RSAPublicKeyFree(firmware_sign_key); | 464 RSAPublicKeyFree(firmware_sign_key); |
| 457 return error_code; /* AKA jump to recovery. */ | 465 return error_code; /* AKA jump to recovery. */ |
| 458 } | 466 } |
| 459 /* Only continue if firmware data verification succeeds. */ | 467 /* Only continue if firmware data verification succeeds. */ |
| 460 firmware_ptr = (preamble_ptr + | 468 firmware_ptr = (preamble_ptr + |
| 461 GetFirmwarePreambleLen(NULL) + | 469 GetFirmwarePreambleLen(NULL) + |
| 462 signature_len); | 470 signature_len); |
| 463 | 471 |
| 464 if ((error_code = VerifyFirmwareData(firmware_sign_key, firmware_ptr, | 472 if ((error_code = VerifyFirmwareData(firmware_sign_key, firmware_ptr, |
| 465 firmware_len, | 473 firmware_len, |
| 466 algorithm))) { | 474 algorithm))) { |
| 467 RSAPublicKeyFree(firmware_sign_key); | 475 RSAPublicKeyFree(firmware_sign_key); |
| 468 return error_code; /* AKA jump to recovery. */ | 476 return error_code; /* AKA jump to recovery. */ |
| 469 } | 477 } |
| 470 | 478 |
| 471 RSAPublicKeyFree(firmware_sign_key); | 479 RSAPublicKeyFree(firmware_sign_key); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 487 if (!image) | 495 if (!image) |
| 488 return VERIFY_FIRMWARE_INVALID_IMAGE; | 496 return VERIFY_FIRMWARE_INVALID_IMAGE; |
| 489 | 497 |
| 490 /* Verify root key signature on the sign key header if we | 498 /* Verify root key signature on the sign key header if we |
| 491 * are not in dev mode. | 499 * are not in dev mode. |
| 492 * | 500 * |
| 493 * TODO(gauravsh): Add additional sanity checks here for: | 501 * TODO(gauravsh): Add additional sanity checks here for: |
| 494 * 1) verifying the header length is correct. | 502 * 1) verifying the header length is correct. |
| 495 * 2) header_checksum is correct. | 503 * 2) header_checksum is correct. |
| 496 */ | 504 */ |
| 505 /* TODO(gauravsh): The [dev_mode] switch is actually irrelevant |
| 506 * for the firmware verification. |
| 507 * Change this to always verify the root key signature and change |
| 508 * test expectations appropriately. |
| 509 */ |
| 497 if (!dev_mode) { | 510 if (!dev_mode) { |
| 498 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM); | 511 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM); |
| 499 DigestUpdate(&ctx, (uint8_t*) &image->header_len, | 512 DigestUpdate(&ctx, (uint8_t*) &image->header_len, |
| 500 FIELD_LEN(header_len)); | 513 FIELD_LEN(header_len)); |
| 501 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, | 514 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, |
| 502 FIELD_LEN(firmware_sign_algorithm)); | 515 FIELD_LEN(firmware_sign_algorithm)); |
| 516 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, |
| 517 FIELD_LEN(firmware_key_version)); |
| 503 DigestUpdate(&ctx, image->firmware_sign_key, | 518 DigestUpdate(&ctx, image->firmware_sign_key, |
| 504 RSAProcessedKeySize(image->firmware_sign_algorithm)); | 519 RSAProcessedKeySize(image->firmware_sign_algorithm)); |
| 505 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, | |
| 506 FIELD_LEN(firmware_key_version)); | |
| 507 DigestUpdate(&ctx, image->header_checksum, | 520 DigestUpdate(&ctx, image->header_checksum, |
| 508 FIELD_LEN(header_checksum)); | 521 FIELD_LEN(header_checksum)); |
| 509 header_digest = DigestFinal(&ctx); | 522 header_digest = DigestFinal(&ctx); |
| 510 if (!RSAVerify(root_key, image->firmware_key_signature, | 523 if (!RSAVerify(root_key, image->firmware_key_signature, |
| 511 FIELD_LEN(firmware_key_signature), | 524 FIELD_LEN(firmware_key_signature), |
| 512 ROOT_SIGNATURE_ALGORITHM, | 525 ROOT_SIGNATURE_ALGORITHM, |
| 513 header_digest)) { | 526 header_digest)) { |
| 514 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | 527 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
| 515 goto verify_failure; | 528 goto verify_failure; |
| 516 } | 529 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 if (!(firmware_signature = SignatureBuf(image->firmware_data, | 619 if (!(firmware_signature = SignatureBuf(image->firmware_data, |
| 607 image->firmware_len, | 620 image->firmware_len, |
| 608 signing_key_file, | 621 signing_key_file, |
| 609 image->firmware_sign_algorithm))) | 622 image->firmware_sign_algorithm))) |
| 610 return 0; | 623 return 0; |
| 611 image->firmware_signature = (uint8_t*) Malloc(signature_len); | 624 image->firmware_signature = (uint8_t*) Malloc(signature_len); |
| 612 Memcpy(image->firmware_signature, firmware_signature, signature_len); | 625 Memcpy(image->firmware_signature, firmware_signature, signature_len); |
| 613 Free(firmware_signature); | 626 Free(firmware_signature); |
| 614 return 1; | 627 return 1; |
| 615 } | 628 } |
| 629 |
| 630 uint32_t GetLogicalFirmwareVersion(uint8_t* firmware_blob) { |
| 631 uint16_t firmware_key_version; |
| 632 uint16_t firmware_version; |
| 633 uint16_t firmware_sign_algorithm; |
| 634 int firmware_sign_key_len; |
| 635 Memcpy(&firmware_sign_algorithm, |
| 636 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ |
| 637 FIELD_LEN(header_len)), |
| 638 sizeof(firmware_sign_algorithm)); |
| 639 Memcpy(&firmware_key_version, |
| 640 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ |
| 641 FIELD_LEN(header_len) + |
| 642 FIELD_LEN(firmware_sign_algorithm)), |
| 643 sizeof(firmware_key_version)); |
| 644 if (firmware_sign_algorithm >= kNumAlgorithms) |
| 645 return 0; |
| 646 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); |
| 647 Memcpy(&firmware_version, |
| 648 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ |
| 649 FIELD_LEN(header_len) + |
| 650 FIELD_LEN(firmware_key_version) + |
| 651 firmware_sign_key_len + |
| 652 FIELD_LEN(header_checksum) + |
| 653 FIELD_LEN(firmware_key_signature)), |
| 654 sizeof(firmware_version)); |
| 655 return CombineUint16Pair(firmware_key_version, firmware_version); |
| 656 } |
| 657 |
| 658 int VerifyFirmwareDriver_f(uint8_t* root_key_blob, |
| 659 uint8_t* firmwareA, |
| 660 uint8_t* firmwareB) { |
| 661 /* Contains the logical firmware version (32-bit) which is calculated as |
| 662 * (firmware_key_version << 16 | firmware_version) where |
| 663 * [firmware_key_version] [firmware_version] are both 16-bit. |
| 664 */ |
| 665 uint32_t firmwareA_lversion, firmwareB_lversion; |
| 666 uint8_t firmwareA_is_verified = 0; /* Whether firmwareA verify succeeded. */ |
| 667 uint32_t min_lversion; /* Minimum of firmware A and firmware lversion. */ |
| 668 uint32_t stored_lversion; /* Stored logical version in the TPM. */ |
| 669 |
| 670 /* Initialize the TPM since we'll be reading the rollback indices. */ |
| 671 SetupTPM(); |
| 672 |
| 673 /* We get the key versions by reading directly from the image blobs without |
| 674 * any additional (expensive) sanity checking on the blob since it's faster to |
| 675 * outright reject a firmware with an older firmware key version. A malformed |
| 676 * or corrupted firmware blob will still fail when VerifyFirmware() is called |
| 677 * on it. |
| 678 */ |
| 679 firmwareA_lversion = GetLogicalFirmwareVersion(firmwareA); |
| 680 firmwareB_lversion = GetLogicalFirmwareVersion(firmwareB); |
| 681 min_lversion = Min(firmwareA_lversion, firmwareB_lversion); |
| 682 stored_lversion = CombineUint16Pair(GetStoredVersion(FIRMWARE_KEY_VERSION), |
| 683 GetStoredVersion(FIRMWARE_VERSION)); |
| 684 /* Always try FirmwareA first. */ |
| 685 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareA, |
| 686 0)) |
| 687 firmwareA_is_verified = 1; |
| 688 if (firmwareA_is_verified && (stored_lversion < firmwareA_lversion)) { |
| 689 /* Stored version may need to be updated but only if FirmwareB |
| 690 * is successfully verified and has a logical version greater than |
| 691 * the stored logical version. */ |
| 692 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB, |
| 693 0)) { |
| 694 if (stored_lversion < firmwareB_lversion) { |
| 695 WriteStoredVersion(FIRMWARE_KEY_VERSION, |
| 696 (uint16_t) (min_lversion >> 16)); |
| 697 WriteStoredVersion(FIRMWARE_VERSION, |
| 698 (uint16_t) (min_lversion & 0x00FFFF)); |
| 699 stored_lversion = min_lversion; /* Update stored version as it's used |
| 700 * later. */ |
| 701 } |
| 702 } |
| 703 } |
| 704 /* Lock Firmware TPM rollback indices from further writes. */ |
| 705 /* TODO(gauravsh): Figure out if these can be combined into one |
| 706 * 32-bit location since we seem to always use them together. This can help |
| 707 * us minimize the number of NVRAM writes/locks (which are limited over flash |
| 708 * memory lifetimes. |
| 709 */ |
| 710 LockStoredVersion(FIRMWARE_KEY_VERSION); |
| 711 LockStoredVersion(FIRMWARE_VERSION); |
| 712 |
| 713 /* Determine which firmware (if any) to jump to. |
| 714 * |
| 715 * We always attempt to jump to FirmwareA first. If verification of FirmwareA |
| 716 * fails, we try FirmwareB. In all cases, if the firmware successfully |
| 717 * verified but is a rollback, we jump to recovery. |
| 718 * |
| 719 * Note: This means that if FirmwareA verified successfully and is a |
| 720 * rollback, then no attempt is made to check FirmwareB. We still jump to |
| 721 * recovery. FirmwareB is only used as a backup in case FirmwareA gets |
| 722 * corrupted. Since newer firmware updates are always written to A, |
| 723 * the case where firmware A is verified but a rollback should not occur in |
| 724 * normal operation. |
| 725 */ |
| 726 if (firmwareA_is_verified) { |
| 727 if (stored_lversion <= firmwareA_lversion) |
| 728 return BOOT_FIRMWARE_A_CONTINUE; |
| 729 } else { |
| 730 /* If FirmwareA was not valid, then we skipped over the |
| 731 * check to update the rollback indices and a Verify of FirmwareB wasn't |
| 732 * attempted. |
| 733 * If FirmwareB is not a rollback, then we attempt to do the verification. |
| 734 */ |
| 735 if (stored_lversion <= firmwareB_lversion && |
| 736 (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB, |
| 737 0))) |
| 738 return BOOT_FIRMWARE_B_CONTINUE; |
| 739 } |
| 740 /* D'oh: No bootable firmware. */ |
| 741 return BOOT_FIRMWARE_RECOVERY_CONTINUE; |
| 742 } |
| OLD | NEW |