diff --git a/tests/test_common.c b/tests/test_common.c index 5c39413fbd..8270c3adca 100644 --- a/tests/test_common.c +++ b/tests/test_common.c @@ -72,6 +72,12 @@ FirmwareImage* GenerateTestFirmwareImage(int algorithm, /* Populate firmware and preamble with dummy data. */ image->firmware_version = firmware_version; image->firmware_len = firmware_len; + /* Make the kernel subkey the same as the firmware signing key. */ + image->kernel_subkey_sign_algorithm = algorithm; + image->kernel_subkey_sign_key = (uint8_t*) Malloc( + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); + Memcpy(image->kernel_subkey_sign_key, firmware_sign_key, + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); image->preamble_signature = image->firmware_signature = NULL; Memset(image->preamble, 'P', FIRMWARE_PREAMBLE_SIZE); image->firmware_data = Malloc(image->firmware_len); diff --git a/vboot_firmware/include/firmware_image_fw.h b/vboot_firmware/include/firmware_image_fw.h index 8cba176c4b..fb90f0271b 100644 --- a/vboot_firmware/include/firmware_image_fw.h +++ b/vboot_firmware/include/firmware_image_fw.h @@ -36,6 +36,10 @@ typedef struct FirmwareImage { /* Firmware Preamble. */ uint16_t firmware_version; /* Firmware Version# for preventing rollbacks.*/ uint64_t firmware_len; /* Length of the rest of the R/W firmware data. */ + uint16_t kernel_subkey_sign_algorithm; /* Signature algorithm used for + * signing the kernel subkey. */ + uint8_t* kernel_subkey_sign_key; /* Pre-processed public half of the kernel + * subkey signing key. */ uint8_t preamble[FIRMWARE_PREAMBLE_SIZE]; /* Remaining preamble data.*/ uint8_t* preamble_signature; /* Signature over the preamble. */ @@ -65,6 +69,10 @@ typedef struct FirmwareImage { extern char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX]; +/* Returns the length of the verified boot firmware preamble based on + * kernel subkey signing algorithm [algorithm]. */ +uint64_t GetFirmwarePreambleLen(int algorithm); + /* Checks for the sanity of the firmware header pointed by [header_blob]. * * On success, put signature algorithm in [algorithm], header length diff --git a/vboot_firmware/lib/firmware_image_fw.c b/vboot_firmware/lib/firmware_image_fw.c index 9999ed6663..dc86887bab 100644 --- a/vboot_firmware/lib/firmware_image_fw.c +++ b/vboot_firmware/lib/firmware_image_fw.c @@ -29,6 +29,15 @@ char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = { "Firmware Version Rollback." }; +uint64_t GetFirmwarePreambleLen(int algorithm) { + return (FIELD_LEN(firmware_version) + + FIELD_LEN(firmware_len) + + FIELD_LEN(kernel_subkey_sign_algorithm) + + RSAProcessedKeySize(algorithm) + + FIELD_LEN(preamble)); +} + + int VerifyFirmwareHeader(const uint8_t* root_key_blob, const uint8_t* header_blob, int* algorithm, @@ -89,22 +98,24 @@ int VerifyFirmwareHeader(const uint8_t* root_key_blob, int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key, const uint8_t* preamble_blob, - int algorithm, + int firmware_sign_algorithm, uint64_t* firmware_len) { uint64_t len; int preamble_len; uint16_t firmware_version; + uint16_t kernel_subkey_sign_algorithm; Memcpy(&firmware_version, preamble_blob, sizeof(firmware_version)); - - preamble_len = (FIELD_LEN(firmware_version) + - FIELD_LEN(firmware_len) + - FIELD_LEN(preamble)); + Memcpy(&kernel_subkey_sign_algorithm, + preamble_blob + (FIELD_LEN(firmware_version) + + FIELD_LEN(firmware_len)), + FIELD_LEN(kernel_subkey_sign_algorithm)); + preamble_len = GetFirmwarePreambleLen(kernel_subkey_sign_algorithm); if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */ preamble_blob, /* Data to verify */ preamble_len, /* Length of data */ preamble_blob + preamble_len, /* Expected Signature */ - algorithm)) + firmware_sign_algorithm)) return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), @@ -117,19 +128,24 @@ int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, const uint8_t* preamble_start, const uint8_t* firmware_data, uint64_t firmware_len, - int algorithm) { - int signature_len = siglen_map[algorithm]; - int preamble_len = (FIELD_LEN(firmware_version) + - FIELD_LEN(firmware_len) + - FIELD_LEN(preamble));; + int firmware_sign_algorithm) { + int signature_len = siglen_map[firmware_sign_algorithm]; + int preamble_len; + uint16_t kernel_subkey_sign_algorithm; uint8_t* digest = NULL; const uint8_t* firmware_signature = NULL; DigestContext ctx; + Memcpy(&kernel_subkey_sign_algorithm, + preamble_start + (FIELD_LEN(firmware_version) + + FIELD_LEN(firmware_len)), + FIELD_LEN(kernel_subkey_sign_algorithm)); + preamble_len = GetFirmwarePreambleLen(kernel_subkey_sign_algorithm); + /* Since the firmware signature is over the preamble and the firmware data, * which does not form a contiguous region of memory, we calculate the * message digest ourselves. */ - DigestInit(&ctx, algorithm); + DigestInit(&ctx, firmware_sign_algorithm); DigestUpdate(&ctx, preamble_start, preamble_len); DigestUpdate(&ctx, firmware_data, firmware_len); digest = DigestFinal(&ctx); @@ -139,7 +155,7 @@ int VerifyFirmwareData(RSAPublicKey* firmware_sign_key, NULL, firmware_sign_key, /* Key to use. */ digest, /* Digest of the data to verify. */ firmware_signature, /* Expected Signature */ - algorithm)) { + firmware_sign_algorithm)) { Free(digest); return VERIFY_FIRMWARE_SIGNATURE_FAILED; } @@ -151,7 +167,7 @@ int VerifyFirmware(const uint8_t* root_key_blob, const uint8_t* verification_header_blob, const uint8_t* firmware_blob) { int error_code = 0; - int algorithm; /* Signing key algorithm. */ + int firmware_sign_algorithm; /* Signing key algorithm. */ RSAPublicKey* firmware_sign_key = NULL; int firmware_sign_key_len, signature_len, header_len; uint64_t firmware_len; @@ -172,25 +188,26 @@ int VerifyFirmware(const uint8_t* root_key_blob, /* Only continue if header verification succeeds. */ if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, - &algorithm, &header_len))) { + &firmware_sign_algorithm, + &header_len))) { debug("Couldn't verify Firmware header.\n"); return error_code; /* AKA jump to revovery. */ } /* Parse signing key into RSAPublicKey structure since it is required multiple * times. */ - firmware_sign_key_len = RSAProcessedKeySize(algorithm); + firmware_sign_key_len = RSAProcessedKeySize(firmware_sign_algorithm); firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) + FIELD_LEN(firmware_key_version)); firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr, firmware_sign_key_len); - signature_len = siglen_map[algorithm]; + signature_len = siglen_map[firmware_sign_algorithm]; /* Only continue if preamble verification succeeds. */ preamble_ptr = (header_ptr + header_len + FIELD_LEN(firmware_key_signature)); if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr, - algorithm, + firmware_sign_algorithm, &firmware_len))) { RSAPublicKeyFree(firmware_sign_key); debug("Couldn't verify Firmware preamble.\n"); @@ -200,7 +217,7 @@ int VerifyFirmware(const uint8_t* root_key_blob, if ((error_code = VerifyFirmwareData(firmware_sign_key, preamble_ptr, firmware_blob, firmware_len, - algorithm))) { + firmware_sign_algorithm))) { RSAPublicKeyFree(firmware_sign_key); debug("Couldn't verify Firmware data.\n"); return error_code; /* AKA jump to recovery. */ diff --git a/vfirmware/firmware_image.c b/vfirmware/firmware_image.c index d16a1fc70b..829d72ade3 100644 --- a/vfirmware/firmware_image.c +++ b/vfirmware/firmware_image.c @@ -25,6 +25,7 @@ FirmwareImage* FirmwareImageNew(void) { FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage)); if (image) { image->firmware_sign_key = NULL; + image->kernel_subkey_sign_key = NULL; image->preamble_signature = NULL; image->firmware_signature = NULL; image->firmware_data = NULL; @@ -35,6 +36,7 @@ FirmwareImage* FirmwareImageNew(void) { void FirmwareImageFree(FirmwareImage* image) { if (image) { Free(image->firmware_sign_key); + Free(image->kernel_subkey_sign_key); Free(image->preamble_signature); Free(image->firmware_signature); Free(image->firmware_data); @@ -116,6 +118,10 @@ FirmwareImage* ReadFirmwareImage(const char* input_file) { /* Read the firmware preamble. */ StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len)); + StatefulMemcpy(&st, &image->kernel_subkey_sign_algorithm, + FIELD_LEN(kernel_subkey_sign_algorithm)); + StatefulMemcpy(&st, image->kernel_subkey_sign_key, + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble)); /* Read firmware preamble signature. */ @@ -187,22 +193,24 @@ uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { return header_blob; } -int GetFirmwarePreambleLen(void) { - return (FIELD_LEN(firmware_version) + FIELD_LEN(firmware_len) + - FIELD_LEN(preamble)); -} uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) { uint8_t* preamble_blob = NULL; MemcpyState st; + uint64_t preamble_len = GetFirmwarePreambleLen( + image->kernel_subkey_sign_algorithm); - preamble_blob = (uint8_t*) Malloc(GetFirmwarePreambleLen()); - st.remaining_len = GetFirmwarePreambleLen(); + preamble_blob = (uint8_t*) Malloc(preamble_len); + st.remaining_len = preamble_len; st.remaining_buf = preamble_blob; st.overrun = 0; StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version)); StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len)); + StatefulMemcpy_r(&st, &image->kernel_subkey_sign_algorithm, + FIELD_LEN(kernel_subkey_sign_algorithm)); + StatefulMemcpy_r(&st, image->kernel_subkey_sign_key, + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble)); if (st.overrun || st.remaining_len != 0 ) { /* Underrun or Overrun. */ @@ -227,7 +235,7 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { *blob_len = (FIELD_LEN(magic) + GetFirmwareHeaderLen(image) + FIELD_LEN(firmware_key_signature) + - GetFirmwarePreambleLen() + + GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm) + 2 * firmware_signature_len + image->firmware_len); firmware_blob = (uint8_t*) Malloc(*blob_len); @@ -242,7 +250,8 @@ uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { StatefulMemcpy_r(&st, header_blob, GetFirmwareHeaderLen(image)); StatefulMemcpy_r(&st, image->firmware_key_signature, FIELD_LEN(firmware_key_signature)); - StatefulMemcpy_r(&st, preamble_blob, GetFirmwarePreambleLen()); + StatefulMemcpy_r(&st, preamble_blob, + GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm)); StatefulMemcpy_r(&st, image->preamble_signature, firmware_signature_len); StatefulMemcpy_r(&st, image->firmware_signature, firmware_signature_len); StatefulMemcpy_r(&st, image->firmware_data, image->firmware_len); @@ -397,6 +406,10 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key, FIELD_LEN(firmware_version)); DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, FIELD_LEN(firmware_len)); + DigestUpdate(&ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm, + FIELD_LEN(kernel_subkey_sign_algorithm)); + DigestUpdate(&ctx, (uint8_t*) image->kernel_subkey_sign_key, + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); DigestUpdate(&ctx, (uint8_t*) &image->preamble, FIELD_LEN(preamble)); preamble_digest = DigestFinal(&ctx); @@ -414,6 +427,10 @@ int VerifyFirmwareImage(const RSAPublicKey* root_key, FIELD_LEN(firmware_version)); DigestUpdate(&firmware_ctx, (uint8_t*) &image->firmware_len, FIELD_LEN(firmware_len)); + DigestUpdate(&firmware_ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm, + FIELD_LEN(kernel_subkey_sign_algorithm)); + DigestUpdate(&firmware_ctx, (uint8_t*) image->kernel_subkey_sign_key, + RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); DigestUpdate(&firmware_ctx, (uint8_t*) &image->preamble, FIELD_LEN(preamble)); DigestUpdate(&firmware_ctx, image->firmware_data, image->firmware_len); @@ -464,12 +481,14 @@ int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) { uint8_t* firmware_signature = NULL; uint8_t* firmware_buf = NULL; int signature_len = siglen_map[image->firmware_sign_algorithm]; + uint64_t preamble_len = GetFirmwarePreambleLen( + image->kernel_subkey_sign_algorithm); preamble_blob = GetFirmwarePreambleBlob(image); if (!preamble_blob) return 0; if (!(preamble_signature = SignatureBuf(preamble_blob, - GetFirmwarePreambleLen(), + preamble_len, signing_key_file, image->firmware_sign_algorithm))) { Free(preamble_blob); @@ -480,13 +499,13 @@ int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) { Free(preamble_signature); /* Firmware signature must be calculated on preamble + firmware_data * to avoid splicing attacks. */ - firmware_buf = (uint8_t*) Malloc(GetFirmwarePreambleLen() + + firmware_buf = (uint8_t*) Malloc(preamble_len + image->firmware_len); - Memcpy(firmware_buf, preamble_blob, GetFirmwarePreambleLen()); - Memcpy(firmware_buf + GetFirmwarePreambleLen(), image->firmware_data, + Memcpy(firmware_buf, preamble_blob, preamble_len); + Memcpy(firmware_buf + preamble_len, image->firmware_data, image->firmware_len); if (!(firmware_signature = SignatureBuf(firmware_buf, - GetFirmwarePreambleLen() + + preamble_len + image->firmware_len, signing_key_file, image->firmware_sign_algorithm))) {