Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1143)

Unified Diff: vboot_firmware/lib/vboot_firmware.c

Issue 2848006: Refactor LoadFrmware() to avoid global variables, which don't work when running out of ROM (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Undo change to vboot_struct Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « vboot_firmware/lib/vboot_common.c ('k') | vboot_firmware/linktest/main.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
« no previous file with comments | « vboot_firmware/lib/vboot_common.c ('k') | vboot_firmware/linktest/main.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698