Index: firmware/lib/vboot_kernel.c |
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c |
index 3280ba5e17c1bc35e3dc70eed423e2e2468e4b55..4b2a030be39c0467bb4a8e8270a8d4cbe847992c 100644 |
--- a/firmware/lib/vboot_kernel.c |
+++ b/firmware/lib/vboot_kernel.c |
@@ -120,10 +120,8 @@ int LoadKernel(LoadKernelParams* params) { |
uint8_t* kbuf = NULL; |
int found_partitions = 0; |
int good_partition = -1; |
- uint16_t tpm_key_version = 0; |
- uint16_t tpm_kernel_version = 0; |
- uint64_t lowest_key_version = 0xFFFF; |
- uint64_t lowest_kernel_version = 0xFFFF; |
+ uint32_t tpm_version = 0; |
+ uint64_t lowest_version = 0xFFFFFFFF; |
int is_dev; |
int is_rec; |
int is_normal; |
@@ -164,7 +162,7 @@ int LoadKernel(LoadKernelParams* params) { |
if (is_normal) { |
/* Read current kernel key index from TPM. Assumes TPM is already |
* initialized. */ |
- status = RollbackKernelRead(&tpm_key_version, &tpm_kernel_version); |
+ status = RollbackKernelRead(&tpm_version); |
if (0 != status) { |
VBDEBUG(("Unable to get kernel versions from TPM\n")); |
return (status == TPM_E_MUST_REBOOT ? |
@@ -202,6 +200,7 @@ int LoadKernel(LoadKernelParams* params) { |
VbKernelPreambleHeader* preamble; |
RSAPublicKey* data_key; |
uint64_t key_version; |
+ uint64_t combined_version; |
uint64_t body_offset; |
VBDEBUG(("Found kernel entry at %" PRIu64 " size %" PRIu64 "\n", |
@@ -244,7 +243,7 @@ int LoadKernel(LoadKernelParams* params) { |
* skipped in recovery and developer modes because those set |
* key_version=0 above. */ |
key_version = key_block->data_key.key_version; |
- if (key_version < tpm_key_version) { |
+ if (key_version < (tpm_version >> 16)) { |
VBDEBUG(("Key version too old.\n")); |
continue; |
} |
@@ -265,10 +264,11 @@ int LoadKernel(LoadKernelParams* params) { |
} |
/* Check for rollback of kernel version. Note this is implicitly |
- * skipped in recovery and developer modes because those set |
- * key_version=0 and kernel_version=0 above. */ |
- if (key_version == tpm_key_version && |
- preamble->kernel_version < tpm_kernel_version) { |
+ * skipped in recovery and developer modes because rollback_index |
+ * sets those to 0 in those modes. */ |
+ combined_version = ((key_version << 16) | |
+ (preamble->kernel_version & 0xFFFF)); |
+ if (combined_version < tpm_version) { |
VBDEBUG(("Kernel version too low.\n")); |
RSAPublicKeyFree(data_key); |
continue; |
@@ -276,15 +276,9 @@ int LoadKernel(LoadKernelParams* params) { |
VBDEBUG(("Kernel preamble is good.\n")); |
- /* Check for lowest key version from a valid header. */ |
- if (lowest_key_version > key_version) { |
- lowest_key_version = key_version; |
- lowest_kernel_version = preamble->kernel_version; |
- } |
- else if (lowest_key_version == key_version && |
- lowest_kernel_version > preamble->kernel_version) { |
- lowest_kernel_version = preamble->kernel_version; |
- } |
+ /* Check for lowest version from a valid header. */ |
+ if (lowest_version > combined_version) |
+ lowest_version = combined_version; |
/* If we already have a good kernel, no need to read another |
* one; we only needed to look at the versions to check for |
@@ -362,9 +356,8 @@ int LoadKernel(LoadKernelParams* params) { |
* the same as the tpm, then the TPM doesn't need updating; we |
* can stop now. Otherwise, we'll check all the other headers |
* to see if they contain a newer key. */ |
- if (key_version == tpm_key_version && |
- preamble->kernel_version == tpm_kernel_version) { |
- VBDEBUG(("Same key version\n")); |
+ if (combined_version == tpm_version) { |
+ VBDEBUG(("Same kernel version\n")); |
break; |
} |
} /* while(GptNextKernelEntry) */ |
@@ -390,12 +383,8 @@ int LoadKernel(LoadKernelParams* params) { |
* anything we write gets blown away by the firmware when we go |
* back to normal mode. */ |
VBDEBUG(("Boot_flags = is_normal\n")); |
- if ((lowest_key_version > tpm_key_version) || |
- (lowest_key_version == tpm_key_version && |
- lowest_kernel_version > tpm_kernel_version)) { |
- |
- status = RollbackKernelWrite((uint16_t)lowest_key_version, |
- (uint16_t)lowest_kernel_version); |
+ if (lowest_version > tpm_version) { |
+ status = RollbackKernelWrite((uint32_t)lowest_version); |
if (0 != status) { |
VBDEBUG(("Error writing kernel versions to TPM.\n")); |
return (status == TPM_E_MUST_REBOOT ? |