Index: firmware/lib/vboot_firmware.c |
diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c |
index 36f09c9159fa4d04ae7d7cbf1f09169284aa1339..6f20641af5967cabe70b450b4e3be22690de1224 100644 |
--- a/firmware/lib/vboot_firmware.c |
+++ b/firmware/lib/vboot_firmware.c |
@@ -51,16 +51,22 @@ int LoadFirmware(LoadFirmwareParams* params) { |
debug("LoadFirmware started...\n"); |
/* Must have a root key */ |
- if (!root_key) |
+ if (!root_key) { |
+ debug("No root key\n"); |
return LOAD_FIRMWARE_RECOVERY; |
+ } |
/* Initialize the TPM and read rollback indices. */ |
/* TODO: fix SetupTPM parameter for developer mode */ |
- if (0 != SetupTPM(RO_NORMAL_MODE, 0) ) |
+ if (0 != SetupTPM(RO_NORMAL_MODE, 0)) { |
+ debug("SetupTPM failed\n"); |
return LOAD_FIRMWARE_RECOVERY; |
+ } |
if (0 != GetStoredVersions(FIRMWARE_VERSIONS, |
- &tpm_key_version, &tpm_fw_version)) |
+ &tpm_key_version, &tpm_fw_version)) { |
+ debug("Unable to get stored versions.\n"); |
return LOAD_FIRMWARE_RECOVERY; |
+ } |
/* Allocate our internal data */ |
lfi = (VbLoadFirmwareInternal*)Malloc(sizeof(VbLoadFirmwareInternal)); |
@@ -85,18 +91,24 @@ int LoadFirmware(LoadFirmwareParams* params) { |
key_block = (VbKeyBlockHeader*)params->verification_block_1; |
vblock_size = params->verification_size_1; |
} |
- if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) |
+ if ((0 != KeyBlockVerify(key_block, vblock_size, root_key))) { |
+ debug("Key block verification failed.\n"); |
continue; |
+ } |
/* Check for rollback of key version. */ |
key_version = key_block->data_key.key_version; |
- if (key_version < tpm_key_version) |
+ if (key_version < tpm_key_version) { |
+ debug("Key rollback detected.\n"); |
continue; |
+ } |
/* Get the key for preamble/data verification from the key block. */ |
data_key = PublicKeyToRSA(&key_block->data_key); |
- if (!data_key) |
+ if (!data_key) { |
+ debug("Unable to parse data key.\n"); |
continue; |
+ } |
/* Verify the preamble, which follows the key block. */ |
preamble = (VbFirmwarePreambleHeader*)((uint8_t*)key_block + |
@@ -104,6 +116,7 @@ int LoadFirmware(LoadFirmwareParams* params) { |
if ((0 != VerifyFirmwarePreamble2(preamble, |
vblock_size - key_block->key_block_size, |
data_key))) { |
+ debug("Preamble verfication failed.\n"); |
RSAPublicKeyFree(data_key); |
continue; |
} |
@@ -111,6 +124,7 @@ int LoadFirmware(LoadFirmwareParams* params) { |
/* Check for rollback of firmware version. */ |
if (key_version == tpm_key_version && |
preamble->firmware_version < tpm_fw_version) { |
+ debug("Firmware version rollback detected.\n"); |
RSAPublicKeyFree(data_key); |
continue; |
} |
@@ -134,8 +148,14 @@ int LoadFirmware(LoadFirmwareParams* params) { |
/* Read the firmware data */ |
DigestInit(&lfi->body_digest_context, data_key->algorithm); |
lfi->body_size_accum = 0; |
- if ((0 != GetFirmwareBody(params, index)) || |
- (lfi->body_size_accum != preamble->body_signature.data_size)) { |
+ if (0 != GetFirmwareBody(params, index)) { |
+ debug("GetFirmwareBody() failed for index %d\n", index); |
+ RSAPublicKeyFree(data_key); |
+ continue; |
+ } |
+ if (lfi->body_size_accum != preamble->body_signature.data_size) { |
+ debug("Hash updated %d bytes but expected %d\n", |
+ (int)lfi->body_size_accum, (int)preamble->body_signature.data_size); |
RSAPublicKeyFree(data_key); |
continue; |
} |
@@ -143,6 +163,7 @@ int LoadFirmware(LoadFirmwareParams* params) { |
/* Verify firmware data */ |
body_digest = DigestFinal(&lfi->body_digest_context); |
if (0 != VerifyDigest(body_digest, &preamble->body_signature, data_key)) { |
+ debug("Firmware body verification failed.\n"); |
RSAPublicKeyFree(data_key); |
Free(body_digest); |
continue; |
@@ -153,6 +174,7 @@ int LoadFirmware(LoadFirmwareParams* params) { |
Free(body_digest); |
/* If we're still here, the firmware is valid. */ |
+ debug("Firmware %d is valid.\n", index); |
if (-1 == good_index) { |
VbPublicKey *kdest = (VbPublicKey*)params->kernel_sign_key_blob; |
@@ -160,9 +182,11 @@ int LoadFirmware(LoadFirmwareParams* params) { |
PublicKeyInit(kdest, (uint8_t*)(kdest + 1), |
(params->kernel_sign_key_size - sizeof(VbPublicKey))); |
- if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) |
+ if (0 != PublicKeyCopy(kdest, &preamble->kernel_subkey)) { |
+ debug("Kernel subkey too big for buffer.\n"); |
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; |
@@ -195,20 +219,26 @@ int LoadFirmware(LoadFirmwareParams* params) { |
lowest_fw_version > tpm_fw_version)) { |
if (0 != WriteStoredVersions(FIRMWARE_VERSIONS, |
(uint16_t)lowest_key_version, |
- (uint16_t)lowest_fw_version)) |
+ (uint16_t)lowest_fw_version)) { |
+ debug("Unable to write stored versions.\n"); |
return LOAD_FIRMWARE_RECOVERY; |
+ } |
} |
/* Lock Firmware TPM rollback indices from further writes. In |
* this design, this is done by setting the globalLock bit, which |
* is cleared only by TPM_Init at reboot. */ |
- if (0 != LockFirmwareVersions()) |
+ if (0 != LockFirmwareVersions()) { |
+ debug("Unable to lock firmware versions.\n"); |
return LOAD_FIRMWARE_RECOVERY; |
+ } |
/* Success */ |
+ debug("Will boot firmware index %d\n", (int)params->firmware_index); |
return LOAD_FIRMWARE_SUCCESS; |
} |
/* If we're still here, no good firmware, so go to recovery mode. */ |
+ debug("Alas, no good firmware.\n"); |
return LOAD_FIRMWARE_RECOVERY; |
} |