| 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> | |
| 13 #include <sys/types.h> | 12 #include <sys/types.h> |
| 14 #include <sys/stat.h> | 13 #include <sys/stat.h> |
| 15 #include <unistd.h> | 14 #include <unistd.h> |
| 16 | 15 |
| 17 #include "file_keys.h" | 16 #include "file_keys.h" |
| 18 #include "padding.h" | 17 #include "padding.h" |
| 19 #include "rollback_index.h" | |
| 20 #include "rsa_utility.h" | 18 #include "rsa_utility.h" |
| 21 #include "sha_utility.h" | 19 #include "sha_utility.h" |
| 22 #include "signature_digest.h" | 20 #include "signature_digest.h" |
| 23 #include "utility.h" | 21 #include "utility.h" |
| 24 | 22 |
| 25 /* Macro to determine the size of a field structure in the FirmwareImage | 23 /* Macro to determine the size of a field structure in the FirmwareImage |
| 26 * structure. */ | 24 * structure. */ |
| 27 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) | 25 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) |
| 28 | 26 |
| 29 FirmwareImage* FirmwareImageNew(void) { | 27 FirmwareImage* FirmwareImageNew(void) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 firmware_buf = BufferFromFile(input_file, &file_size); | 62 firmware_buf = BufferFromFile(input_file, &file_size); |
| 65 image_len = file_size; | 63 image_len = file_size; |
| 66 | 64 |
| 67 st.remaining_len = image_len; | 65 st.remaining_len = image_len; |
| 68 st.remaining_buf = firmware_buf; | 66 st.remaining_buf = firmware_buf; |
| 69 st.overrun = 0; | 67 st.overrun = 0; |
| 70 | 68 |
| 71 /* Read and compare magic bytes. */ | 69 /* Read and compare magic bytes. */ |
| 72 StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE); | 70 StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE); |
| 73 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) { | 71 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) { |
| 74 fprintf(stderr, "Wrong Firmware Magic.\n"); | 72 debug("Wrong Firmware Magic.\n"); |
| 75 Free(firmware_buf); | 73 Free(firmware_buf); |
| 76 return NULL; | 74 return NULL; |
| 77 } | 75 } |
| 78 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); | 76 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); |
| 79 StatefulMemcpy(&st, &image->firmware_sign_algorithm, | 77 StatefulMemcpy(&st, &image->firmware_sign_algorithm, |
| 80 FIELD_LEN(firmware_sign_algorithm)); | 78 FIELD_LEN(firmware_sign_algorithm)); |
| 81 | 79 |
| 82 /* Valid Algorithm? */ | 80 /* Valid Algorithm? */ |
| 83 if (image->firmware_sign_algorithm >= kNumAlgorithms) { | 81 if (image->firmware_sign_algorithm >= kNumAlgorithms) { |
| 84 Free(firmware_buf); | 82 Free(firmware_buf); |
| 85 return NULL; | 83 return NULL; |
| 86 } | 84 } |
| 87 | 85 |
| 88 /* Compute size of pre-processed RSA public key and signature. */ | 86 /* Compute size of pre-processed RSA public key and signature. */ |
| 89 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); | 87 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); |
| 90 signature_len = siglen_map[image->firmware_sign_algorithm]; | 88 signature_len = siglen_map[image->firmware_sign_algorithm]; |
| 91 | 89 |
| 92 /* Check whether the header length is correct. */ | 90 /* Check whether the header length is correct. */ |
| 93 header_len = GetFirmwareHeaderLen(image); | 91 header_len = GetFirmwareHeaderLen(image); |
| 94 if (header_len != image->header_len) { | 92 if (header_len != image->header_len) { |
| 95 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n", | 93 debug("Header length mismatch. Got: %d Expected: %d\n", |
| 96 image->header_len, header_len); | 94 image->header_len, header_len); |
| 97 Free(firmware_buf); | 95 Free(firmware_buf); |
| 98 return NULL; | 96 return NULL; |
| 99 } | 97 } |
| 100 | 98 |
| 101 /* Read pre-processed public half of the sign key. */ | 99 /* Read pre-processed public half of the sign key. */ |
| 102 StatefulMemcpy(&st, &image->firmware_key_version, | 100 StatefulMemcpy(&st, &image->firmware_key_version, |
| 103 FIELD_LEN(firmware_key_version)); | 101 FIELD_LEN(firmware_key_version)); |
| 104 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); | 102 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); |
| 105 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); | 103 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); |
| 106 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); | 104 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); |
| 107 | 105 |
| 108 /* Check whether the header checksum matches. */ | 106 /* Check whether the header checksum matches. */ |
| 109 CalculateFirmwareHeaderChecksum(image, header_checksum); | 107 CalculateFirmwareHeaderChecksum(image, header_checksum); |
| 110 if (SafeMemcmp(header_checksum, image->header_checksum, | 108 if (SafeMemcmp(header_checksum, image->header_checksum, |
| 111 FIELD_LEN(header_checksum))) { | 109 FIELD_LEN(header_checksum))) { |
| 112 fprintf(stderr, "Invalid firmware header checksum!\n"); | 110 debug("Invalid firmware header checksum!\n"); |
| 113 Free(firmware_buf); | 111 Free(firmware_buf); |
| 114 return NULL; | 112 return NULL; |
| 115 } | 113 } |
| 116 | 114 |
| 117 /* Read key signature. */ | 115 /* Read key signature. */ |
| 118 StatefulMemcpy(&st, image->firmware_key_signature, | 116 StatefulMemcpy(&st, image->firmware_key_signature, |
| 119 FIELD_LEN(firmware_key_signature)); | 117 FIELD_LEN(firmware_key_signature)); |
| 120 | 118 |
| 121 /* Read the firmware preamble. */ | 119 /* Read the firmware preamble. */ |
| 122 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); | 120 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 | 262 |
| 265 int WriteFirmwareImage(const char* input_file, | 263 int WriteFirmwareImage(const char* input_file, |
| 266 const FirmwareImage* image) { | 264 const FirmwareImage* image) { |
| 267 int fd; | 265 int fd; |
| 268 uint8_t* firmware_blob; | 266 uint8_t* firmware_blob; |
| 269 uint64_t blob_len; | 267 uint64_t blob_len; |
| 270 | 268 |
| 271 if (!image) | 269 if (!image) |
| 272 return 0; | 270 return 0; |
| 273 if (-1 == (fd = creat(input_file, S_IRWXU))) { | 271 if (-1 == (fd = creat(input_file, S_IRWXU))) { |
| 274 fprintf(stderr, "Couldn't open file for writing.\n"); | 272 debug("Couldn't open file for writing.\n"); |
| 275 return 0; | 273 return 0; |
| 276 } | 274 } |
| 277 | 275 |
| 278 firmware_blob = GetFirmwareBlob(image, &blob_len); | 276 firmware_blob = GetFirmwareBlob(image, &blob_len); |
| 279 if (!firmware_blob) { | 277 if (!firmware_blob) { |
| 280 fprintf(stderr, "Couldn't create firmware blob from FirmwareImage.\n"); | 278 debug("Couldn't create firmware blob from FirmwareImage.\n"); |
| 281 return 0; | 279 return 0; |
| 282 } | 280 } |
| 283 if (blob_len != write(fd, firmware_blob, blob_len)) { | 281 if (blob_len != write(fd, firmware_blob, blob_len)) { |
| 284 fprintf(stderr, "Couldn't write Firmware Image to file: %s\n", input_file); | 282 debug("Couldn't write Firmware Image to file: %s\n", input_file); |
| 285 Free(firmware_blob); | 283 Free(firmware_blob); |
| 286 close(fd); | 284 close(fd); |
| 287 return 0; | 285 return 0; |
| 288 } | 286 } |
| 289 Free(firmware_blob); | 287 Free(firmware_blob); |
| 290 close(fd); | 288 close(fd); |
| 291 return 1; | 289 return 1; |
| 292 } | 290 } |
| 293 | 291 |
| 294 void PrintFirmwareImage(const FirmwareImage* image) { | 292 void PrintFirmwareImage(const FirmwareImage* image) { |
| 295 if (!image) | 293 if (!image) |
| 296 return; | 294 return; |
| 297 | 295 |
| 298 /* Print header. */ | 296 /* Print header. */ |
| 299 printf("Header Length = %d\n" | 297 debug("Header Length = %d\n" |
| 300 "Firmware Signature Algorithm = %s\n" | 298 "Firmware Signature Algorithm = %s\n" |
| 301 "Firmware Key Version = %d\n\n", | 299 "Firmware Key Version = %d\n\n", |
| 302 image->header_len, | 300 image->header_len, |
| 303 algo_strings[image->firmware_sign_algorithm], | 301 algo_strings[image->firmware_sign_algorithm], |
| 304 image->firmware_key_version); | 302 image->firmware_key_version); |
| 305 /* TODO(gauravsh): Output hash and key signature here? */ | 303 /* TODO(gauravsh): Output hash and key signature here? */ |
| 306 /* Print preamble. */ | 304 /* Print preamble. */ |
| 307 printf("Firmware Version = %d\n" | 305 debug("Firmware Version = %d\n" |
| 308 "Firmware Length = %" PRIu64 "\n\n", | 306 "Firmware Length = %" PRIu64 "\n\n", |
| 309 image->firmware_version, | 307 image->firmware_version, |
| 310 image->firmware_len); | 308 image->firmware_len); |
| 311 /* Output key signature here? */ | 309 /* Output key signature here? */ |
| 312 } | 310 } |
| 313 | 311 |
| 314 char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = { | |
| 315 "Success.", | |
| 316 "Invalid Image.", | |
| 317 "Root Key Signature Failed.", | |
| 318 "Invalid Verification Algorithm.", | |
| 319 "Preamble Signature Failed.", | |
| 320 "Firmware Signature Failed.", | |
| 321 "Wrong Firmware Magic.", | |
| 322 "Invalid Firmware Header Checksum.", | |
| 323 "Firmware Signing Key Rollback.", | |
| 324 "Firmware Version Rollback." | |
| 325 }; | |
| 326 | |
| 327 int VerifyFirmwareHeader(const uint8_t* root_key_blob, | |
| 328 const uint8_t* header_blob, | |
| 329 int* algorithm, | |
| 330 int* header_len) { | |
| 331 int firmware_sign_key_len; | |
| 332 int root_key_len; | |
| 333 uint16_t hlen, algo; | |
| 334 uint8_t* header_checksum = NULL; | |
| 335 | |
| 336 /* Base Offset for the header_checksum field. Actual offset is | |
| 337 * this + firmware_sign_key_len. */ | |
| 338 int base_header_checksum_offset = (FIELD_LEN(header_len) + | |
| 339 FIELD_LEN(firmware_sign_algorithm) + | |
| 340 FIELD_LEN(firmware_key_version)); | |
| 341 | |
| 342 | |
| 343 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM); | |
| 344 Memcpy(&hlen, header_blob, sizeof(hlen)); | |
| 345 Memcpy(&algo, | |
| 346 header_blob + FIELD_LEN(firmware_sign_algorithm), | |
| 347 sizeof(algo)); | |
| 348 if (algo >= kNumAlgorithms) | |
| 349 return VERIFY_FIRMWARE_INVALID_ALGORITHM; | |
| 350 *algorithm = (int) algo; | |
| 351 firmware_sign_key_len = RSAProcessedKeySize(*algorithm); | |
| 352 | |
| 353 /* Verify that header len is correct. */ | |
| 354 if (hlen != (base_header_checksum_offset + | |
| 355 firmware_sign_key_len + | |
| 356 FIELD_LEN(header_checksum))) | |
| 357 return VERIFY_FIRMWARE_INVALID_IMAGE; | |
| 358 | |
| 359 *header_len = (int) hlen; | |
| 360 | |
| 361 /* Verify if the hash of the header is correct. */ | |
| 362 header_checksum = DigestBuf(header_blob, | |
| 363 *header_len - FIELD_LEN(header_checksum), | |
| 364 SHA512_DIGEST_ALGORITHM); | |
| 365 if (SafeMemcmp(header_checksum, | |
| 366 header_blob + (base_header_checksum_offset + | |
| 367 firmware_sign_key_len), | |
| 368 FIELD_LEN(header_checksum))) { | |
| 369 Free(header_checksum); | |
| 370 return VERIFY_FIRMWARE_WRONG_HEADER_CHECKSUM; | |
| 371 } | |
| 372 Free(header_checksum); | |
| 373 | |
| 374 /* Root key signature on the firmware signing key is always checked | |
| 375 * irrespective of dev mode. */ | |
| 376 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */ | |
| 377 header_blob, /* Data to verify */ | |
| 378 *header_len, /* Length of data */ | |
| 379 header_blob + *header_len, /* Expected Signature */ | |
| 380 ROOT_SIGNATURE_ALGORITHM)) | |
| 381 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | |
| 382 return 0; | |
| 383 } | |
| 384 | |
| 385 int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, | |
| 386 const uint8_t* preamble_blob, | |
| 387 int algorithm, | |
| 388 uint64_t* firmware_len) { | |
| 389 uint64_t len; | |
| 390 int preamble_len; | |
| 391 uint16_t firmware_version; | |
| 392 | |
| 393 Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version)); | |
| 394 | |
| 395 preamble_len = (FIELD_LEN(firmware_version) + | |
| 396 FIELD_LEN(firmware_len) + | |
| 397 FIELD_LEN(preamble)); | |
| 398 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ | |
| 399 preamble_blob, /* Data to verify */ | |
| 400 preamble_len, /* Length of data */ | |
| 401 preamble_blob + preamble_len, /* Expected Signature */ | |
| 402 algorithm)) | |
| 403 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; | |
| 404 | |
| 405 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), | |
| 406 sizeof(len)); | |
| 407 *firmware_len = len; | |
| 408 return 0; | |
| 409 } | |
| 410 | |
| 411 int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, | |
| 412 const uint8_t* preamble_start, | |
| 413 const uint8_t* firmware_data_start, | |
| 414 uint64_t firmware_len, | |
| 415 int algorithm) { | |
| 416 int signature_len = siglen_map[algorithm]; | |
| 417 uint8_t* digest; | |
| 418 DigestContext ctx; | |
| 419 | |
| 420 /* Since the firmware signature is over the preamble and the firmware data, | |
| 421 * which does not form a contiguous region of memory, we calculate the | |
| 422 * message digest ourselves. */ | |
| 423 DigestInit(&ctx, algorithm); | |
| 424 DigestUpdate(&ctx, preamble_start, GetFirmwarePreambleLen()); | |
| 425 DigestUpdate(&ctx, firmware_data_start + signature_len, firmware_len); | |
| 426 digest = DigestFinal(&ctx); | |
| 427 if (!RSAVerifyBinaryWithDigest_f( | |
| 428 NULL, firmware_sign_key, /* Key to use. */ | |
| 429 digest, /* Digest of the data to verify. */ | |
| 430 firmware_data_start, /* Expected Signature */ | |
| 431 algorithm)) { | |
| 432 Free(digest); | |
| 433 return VERIFY_FIRMWARE_SIGNATURE_FAILED; | |
| 434 } | |
| 435 Free(digest); | |
| 436 return 0; | |
| 437 } | |
| 438 | |
| 439 int VerifyFirmware(const uint8_t* root_key_blob, | |
| 440 const uint8_t* firmware_blob) { | |
| 441 int error_code = 0; | |
| 442 int algorithm; /* Signing key algorithm. */ | |
| 443 RSAPublicKey* firmware_sign_key = NULL; | |
| 444 int firmware_sign_key_len, signature_len, header_len; | |
| 445 uint64_t firmware_len; | |
| 446 const uint8_t* header_ptr = NULL; /* Pointer to header. */ | |
| 447 const uint8_t* firmware_sign_key_ptr = NULL; /* Pointer to signing key. */ | |
| 448 const uint8_t* preamble_ptr = NULL; /* Pointer to preamble block. */ | |
| 449 const uint8_t* firmware_ptr = NULL; /* Pointer to firmware signature/data. */ | |
| 450 | |
| 451 /* Note: All the offset calculations are based on struct FirmwareImage which | |
| 452 * is defined in include/firmware_image.h. */ | |
| 453 | |
| 454 /* Compare magic bytes. */ | |
| 455 if (SafeMemcmp(firmware_blob, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) | |
| 456 return VERIFY_FIRMWARE_WRONG_MAGIC; | |
| 457 header_ptr = firmware_blob + FIRMWARE_MAGIC_SIZE; | |
| 458 | |
| 459 /* Only continue if header verification succeeds. */ | |
| 460 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, | |
| 461 &algorithm, &header_len))) | |
| 462 return error_code; /* AKA jump to revovery. */ | |
| 463 | |
| 464 /* Parse signing key into RSAPublicKey structure since it is required multiple | |
| 465 * times. */ | |
| 466 firmware_sign_key_len = RSAProcessedKeySize(algorithm); | |
| 467 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + | |
| 468 FIELD_LEN(firmware_sign_algorithm) + | |
| 469 FIELD_LEN(firmware_key_version)); | |
| 470 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, | |
| 471 firmware_sign_key_len); | |
| 472 signature_len = siglen_map[algorithm]; | |
| 473 | |
| 474 /* Only continue if preamble verification succeeds. */ | |
| 475 preamble_ptr = (header_ptr + header_len + | |
| 476 FIELD_LEN(firmware_key_signature)); | |
| 477 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, | |
| 478 algorithm, | |
| 479 &firmware_len))) { | |
| 480 RSAPublicKeyFree(firmware_sign_key); | |
| 481 fprintf(stderr, "Couldn't verify Firmware preamble.\n"); | |
| 482 return error_code; /* AKA jump to recovery. */ | |
| 483 } | |
| 484 /* Only continue if firmware data verification succeeds. */ | |
| 485 firmware_ptr = (preamble_ptr + | |
| 486 GetFirmwarePreambleLen() + | |
| 487 signature_len); | |
| 488 | |
| 489 if ((error_code = VerifyFirmwareData(firmware_sign_key, preamble_ptr, | |
| 490 firmware_ptr, | |
| 491 firmware_len, | |
| 492 algorithm))) { | |
| 493 RSAPublicKeyFree(firmware_sign_key); | |
| 494 fprintf(stderr, "Couldn't verify Firmware data.\n"); | |
| 495 return error_code; /* AKA jump to recovery. */ | |
| 496 } | |
| 497 | |
| 498 RSAPublicKeyFree(firmware_sign_key); | |
| 499 return 0; /* Success! */ | |
| 500 } | |
| 501 | |
| 502 int VerifyFirmwareImage(const RSAPublicKey* root_key, | 312 int VerifyFirmwareImage(const RSAPublicKey* root_key, |
| 503 const FirmwareImage* image) { | 313 const FirmwareImage* image) { |
| 504 RSAPublicKey* firmware_sign_key = NULL; | 314 RSAPublicKey* firmware_sign_key = NULL; |
| 505 uint8_t* header_digest = NULL; | 315 uint8_t* header_digest = NULL; |
| 506 uint8_t* preamble_digest = NULL; | 316 uint8_t* preamble_digest = NULL; |
| 507 uint8_t* firmware_digest = NULL; | 317 uint8_t* firmware_digest = NULL; |
| 508 int firmware_sign_key_size; | 318 int firmware_sign_key_size; |
| 509 int signature_size; | 319 int signature_size; |
| 510 int error_code = 0; | 320 int error_code = 0; |
| 511 DigestContext ctx; | 321 DigestContext ctx; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 Free(firmware_buf); | 465 Free(firmware_buf); |
| 656 return 0; | 466 return 0; |
| 657 } | 467 } |
| 658 image->firmware_signature = (uint8_t*) Malloc(signature_len); | 468 image->firmware_signature = (uint8_t*) Malloc(signature_len); |
| 659 Memcpy(image->firmware_signature, firmware_signature, signature_len); | 469 Memcpy(image->firmware_signature, firmware_signature, signature_len); |
| 660 Free(firmware_signature); | 470 Free(firmware_signature); |
| 661 Free(firmware_buf); | 471 Free(firmware_buf); |
| 662 Free(preamble_blob); | 472 Free(preamble_blob); |
| 663 return 1; | 473 return 1; |
| 664 } | 474 } |
| 665 | |
| 666 uint32_t GetLogicalFirmwareVersion(uint8_t* firmware_blob) { | |
| 667 uint16_t firmware_key_version; | |
| 668 uint16_t firmware_version; | |
| 669 uint16_t firmware_sign_algorithm; | |
| 670 int firmware_sign_key_len; | |
| 671 Memcpy(&firmware_sign_algorithm, | |
| 672 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ | |
| 673 FIELD_LEN(header_len)), | |
| 674 sizeof(firmware_sign_algorithm)); | |
| 675 Memcpy(&firmware_key_version, | |
| 676 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ | |
| 677 FIELD_LEN(header_len) + | |
| 678 FIELD_LEN(firmware_sign_algorithm)), | |
| 679 sizeof(firmware_key_version)); | |
| 680 if (firmware_sign_algorithm >= kNumAlgorithms) | |
| 681 return 0; | |
| 682 firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); | |
| 683 Memcpy(&firmware_version, | |
| 684 firmware_blob + (FIELD_LEN(magic) + /* Offset to field. */ | |
| 685 FIELD_LEN(header_len) + | |
| 686 FIELD_LEN(firmware_key_version) + | |
| 687 firmware_sign_key_len + | |
| 688 FIELD_LEN(header_checksum) + | |
| 689 FIELD_LEN(firmware_key_signature)), | |
| 690 sizeof(firmware_version)); | |
| 691 return CombineUint16Pair(firmware_key_version, firmware_version); | |
| 692 } | |
| 693 | |
| 694 int VerifyFirmwareDriver_f(uint8_t* root_key_blob, | |
| 695 uint8_t* firmwareA, | |
| 696 uint8_t* firmwareB) { | |
| 697 /* Contains the logical firmware version (32-bit) which is calculated as | |
| 698 * (firmware_key_version << 16 | firmware_version) where | |
| 699 * [firmware_key_version] [firmware_version] are both 16-bit. | |
| 700 */ | |
| 701 uint32_t firmwareA_lversion, firmwareB_lversion; | |
| 702 uint8_t firmwareA_is_verified = 0; /* Whether firmwareA verify succeeded. */ | |
| 703 uint32_t min_lversion; /* Minimum of firmware A and firmware lversion. */ | |
| 704 uint32_t stored_lversion; /* Stored logical version in the TPM. */ | |
| 705 | |
| 706 /* Initialize the TPM since we'll be reading the rollback indices. */ | |
| 707 SetupTPM(); | |
| 708 | |
| 709 /* We get the key versions by reading directly from the image blobs without | |
| 710 * any additional (expensive) sanity checking on the blob since it's faster to | |
| 711 * outright reject a firmware with an older firmware key version. A malformed | |
| 712 * or corrupted firmware blob will still fail when VerifyFirmware() is called | |
| 713 * on it. | |
| 714 */ | |
| 715 firmwareA_lversion = GetLogicalFirmwareVersion(firmwareA); | |
| 716 firmwareB_lversion = GetLogicalFirmwareVersion(firmwareB); | |
| 717 min_lversion = Min(firmwareA_lversion, firmwareB_lversion); | |
| 718 stored_lversion = CombineUint16Pair(GetStoredVersion(FIRMWARE_KEY_VERSION), | |
| 719 GetStoredVersion(FIRMWARE_VERSION)); | |
| 720 /* Always try FirmwareA first. */ | |
| 721 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareA)) | |
| 722 firmwareA_is_verified = 1; | |
| 723 if (firmwareA_is_verified && (stored_lversion < firmwareA_lversion)) { | |
| 724 /* Stored version may need to be updated but only if FirmwareB | |
| 725 * is successfully verified and has a logical version greater than | |
| 726 * the stored logical version. */ | |
| 727 if (stored_lversion < firmwareB_lversion) { | |
| 728 if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB)) { | |
| 729 WriteStoredVersion(FIRMWARE_KEY_VERSION, | |
| 730 (uint16_t) (min_lversion >> 16)); | |
| 731 WriteStoredVersion(FIRMWARE_VERSION, | |
| 732 (uint16_t) (min_lversion & 0x00FFFF)); | |
| 733 stored_lversion = min_lversion; /* Update stored version as it's used | |
| 734 * later. */ | |
| 735 } | |
| 736 } | |
| 737 } | |
| 738 /* Lock Firmware TPM rollback indices from further writes. */ | |
| 739 /* TODO(gauravsh): Figure out if these can be combined into one | |
| 740 * 32-bit location since we seem to always use them together. This can help | |
| 741 * us minimize the number of NVRAM writes/locks (which are limited over flash | |
| 742 * memory lifetimes. | |
| 743 */ | |
| 744 LockStoredVersion(FIRMWARE_KEY_VERSION); | |
| 745 LockStoredVersion(FIRMWARE_VERSION); | |
| 746 | |
| 747 /* Determine which firmware (if any) to jump to. | |
| 748 * | |
| 749 * We always attempt to jump to FirmwareA first. If verification of FirmwareA | |
| 750 * fails, we try FirmwareB. In all cases, if the firmware successfully | |
| 751 * verified but is a rollback, we jump to recovery. | |
| 752 * | |
| 753 * Note: This means that if FirmwareA verified successfully and is a | |
| 754 * rollback, then no attempt is made to check FirmwareB. We still jump to | |
| 755 * recovery. FirmwareB is only used as a backup in case FirmwareA gets | |
| 756 * corrupted. Since newer firmware updates are always written to A, | |
| 757 * the case where firmware A is verified but a rollback should not occur in | |
| 758 * normal operation. | |
| 759 */ | |
| 760 if (firmwareA_is_verified) { | |
| 761 if (stored_lversion <= firmwareA_lversion) | |
| 762 return BOOT_FIRMWARE_A_CONTINUE; | |
| 763 } else { | |
| 764 /* If FirmwareA was not valid, then we skipped over the | |
| 765 * check to update the rollback indices and a Verify of FirmwareB wasn't | |
| 766 * attempted. | |
| 767 * If FirmwareB is not a rollback, then we attempt to do the verification. | |
| 768 */ | |
| 769 if (stored_lversion <= firmwareB_lversion && | |
| 770 (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob, firmwareB))) | |
| 771 return BOOT_FIRMWARE_B_CONTINUE; | |
| 772 } | |
| 773 /* D'oh: No bootable firmware. */ | |
| 774 return BOOT_FIRMWARE_RECOVERY_CONTINUE; | |
| 775 } | |
| OLD | NEW |