Index: vboot_firmware/lib/vboot_firmware.c |
diff --git a/vboot_firmware/lib/vboot_firmware.c b/vboot_firmware/lib/vboot_firmware.c |
index 8ff673c201c173e894c2a84086afafac42299112..16979a448516fd032018c4dad78683bcef3c4dbe 100644 |
--- a/vboot_firmware/lib/vboot_firmware.c |
+++ b/vboot_firmware/lib/vboot_firmware.c |
@@ -17,25 +17,26 @@ |
* optimal to have static variables in a library, but in UEFI the |
* caller is deep inside a different firmware stack and doesn't have a |
* good way to pass the params struct back to us. */ |
-static DigestContext ctx; |
-static uint64_t body_size_accum = 0; |
-static int inside_load_firmware = 0; |
+typedef struct VbLoadFirmwareInternal { |
+ DigestContext ctx; |
+ uint64_t body_size_accum; |
+} VbLoadFirmwareInternal; |
-void UpdateFirmwareBodyHash2(uint8_t* data, uint64_t size) { |
- if (!inside_load_firmware) { |
- debug("UpdateFirmwareBodyHash() called outside LoadFirmware()\n"); |
- return; |
- } |
+void UpdateFirmwareBodyHash(LoadFirmwareParams* params, |
+ uint8_t* data, uint64_t size) { |
+ VbLoadFirmwareInternal* lfi = |
+ (VbLoadFirmwareInternal*)params->load_firmware_internal; |
- DigestUpdate(&ctx, data, size); |
- body_size_accum += size; |
+ DigestUpdate(&lfi->ctx, data, size); |
+ lfi->body_size_accum += size; |
} |
int LoadFirmware2(LoadFirmwareParams* params) { |
VbPublicKey* root_key = (VbPublicKey*)params->firmware_root_key_blob; |
+ VbLoadFirmwareInternal* lfi; |
uint16_t tpm_key_version = 0; |
uint16_t tpm_fw_version = 0; |
@@ -61,6 +62,12 @@ int LoadFirmware2(LoadFirmwareParams* params) { |
&tpm_key_version, &tpm_fw_version)) |
return LOAD_FIRMWARE_RECOVERY; |
+ /* Allocate our internal data */ |
+ lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); |
+ if (!lfi) |
+ return LOAD_FIRMWARE_RECOVERY; |
+ params->load_firmware_internal = lfi; |
+ |
/* Loop over indices */ |
for (index = 0; index < 2; index++) { |
VbKeyBlockHeader* key_block; |
@@ -68,8 +75,6 @@ int LoadFirmware2(LoadFirmwareParams* params) { |
VbFirmwarePreambleHeader* preamble; |
RSAPublicKey* data_key; |
uint64_t key_version; |
- uint8_t* body_data; |
- uint64_t body_size; |
uint8_t* body_digest; |
/* Verify the key block */ |
@@ -127,20 +132,16 @@ int LoadFirmware2(LoadFirmwareParams* params) { |
continue; |
/* Read the firmware data */ |
- DigestInit(&ctx, data_key->algorithm); |
- body_size_accum = 0; |
- inside_load_firmware = 1; |
- body_data = GetFirmwareBody(index, &body_size); |
- inside_load_firmware = 0; |
- body_digest = DigestFinal(&ctx); |
- if (!body_data || (body_size != preamble->body_signature.data_size) || |
- (body_size_accum != body_size)) { |
+ DigestInit(&lfi->ctx, data_key->algorithm); |
+ lfi->body_size_accum = 0; |
+ if ((0 != GetFirmwareBody(params, index)) || |
+ (lfi->body_size_accum != preamble->body_signature.data_size)) { |
RSAPublicKeyFree(data_key); |
- Free(body_digest); |
continue; |
} |
/* Verify firmware data */ |
+ body_digest = DigestFinal(&lfi->ctx); |
if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { |
RSAPublicKeyFree(data_key); |
Free(body_digest); |
@@ -154,11 +155,23 @@ int LoadFirmware2(LoadFirmwareParams* params) { |
/* If we're still here, the firmware is valid. */ |
/* Save the first good firmware we find; that's the one we'll boot */ |
if (-1 == good_index) { |
+ VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; |
+ |
+ /* Copy the kernel sign key blob into the destination buffer */ |
+ PublicKeyInit(kdest, (uint8_t*)(kdest + 1), |
+ (params->kernel_sign_key_size - sizeof(VbPublicKey))); |
+ |
+ if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) |
+ continue; /* The firmware signature was good, but the public |
+ * key was bigger that the caller can handle. */ |
+ |
+ /* Save the key size we actually used */ |
+ params->kernel_sign_key_size = kdest->key_offset + kdest->key_size; |
+ |
+ /* Save the good index, now that we're sure we can actually use |
+ * this firmware. */ |
good_index = index; |
params->firmware_index = index; |
- params->kernel_sign_key_blob = &preamble->kernel_subkey; |
- params->kernel_sign_key_size = (preamble->kernel_subkey.key_offset + |
- preamble->kernel_subkey.key_size); |
/* If the good firmware's key version is the same as the tpm, |
* then the TPM doesn't need updating; we can stop now. |
@@ -170,6 +183,10 @@ int LoadFirmware2(LoadFirmwareParams* params) { |
} |
} |
+ /* Free internal data */ |
+ Free(lfi); |
+ params->load_firmware_internal = NULL; |
+ |
/* Handle finding good firmware */ |
if (good_index >= 0) { |