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