mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-26 19:25:02 +00:00
Change rollback interface so kernel/firmware version numbers are
packed in the calling code rather than in rollback_index. Review URL: http://codereview.chromium.org/3114013
This commit is contained in:
@@ -89,13 +89,10 @@ Call from LoadKernel()
|
||||
|
||||
/* Setup must be called. Pass developer_mode=nonzero if in developer
|
||||
* mode. */
|
||||
/* TODO: use a 32-bit version instead of 2 version pieces */
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint16_t* key_version,
|
||||
uint16_t* version);
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version);
|
||||
|
||||
/* Write may be called if the versions change */
|
||||
/* TODO: use a 32-bit version instead of 2 version pieces */
|
||||
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version);
|
||||
uint32_t RollbackFirmwareWrite(uint32_t version);
|
||||
|
||||
/* Lock must be called */
|
||||
uint32_t RollbackFirmwareLock(void);
|
||||
@@ -111,9 +108,8 @@ uint32_t RollbackKernelRecovery(int developer_mode);
|
||||
|
||||
/* Read and write may be called if not in developer mode. If called in
|
||||
* recovery mode, the effect is undefined. */
|
||||
/* TODO: use a 32-bit version instead of 2 version pieces */
|
||||
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version);
|
||||
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version);
|
||||
uint32_t RollbackKernelRead(uint32_t* version);
|
||||
uint32_t RollbackKernelWrite(uint32_t version);
|
||||
|
||||
/* Lock must be called. Internally, it's ignored in recovery mode. */
|
||||
uint32_t RollbackKernelLock(void);
|
||||
|
||||
@@ -271,8 +271,7 @@ __pragma(warning (disable: 4100))
|
||||
|
||||
/* Dummy implementations which don't support TPM rollback protection */
|
||||
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode,
|
||||
uint16_t* key_version, uint16_t* version) {
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
||||
#ifndef CHROMEOS_ENVIRONMENT
|
||||
/* Initialize the TPM, but ignore return codes. In ChromeOS
|
||||
* environment, don't even talk to the TPM. */
|
||||
@@ -281,11 +280,11 @@ uint32_t RollbackFirmwareSetup(int developer_mode,
|
||||
TlclSelfTestFull();
|
||||
#endif
|
||||
|
||||
*key_version = *version = 0;
|
||||
*version = 0;
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) {
|
||||
uint32_t RollbackFirmwareWrite(uint32_t version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -304,12 +303,12 @@ uint32_t RollbackKernelRecovery(int developer_mode) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) {
|
||||
*key_version = *version = 0;
|
||||
uint32_t RollbackKernelRead(uint32_t* version) {
|
||||
*version = 0;
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) {
|
||||
uint32_t RollbackKernelWrite(uint32_t version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -319,28 +318,22 @@ uint32_t RollbackKernelLock(void) {
|
||||
|
||||
#else
|
||||
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint16_t* key_version,
|
||||
uint16_t* version) {
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
||||
RollbackSpaceFirmware rsf;
|
||||
|
||||
RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf));
|
||||
*key_version = (uint16_t)(rsf.fw_versions >> 16);
|
||||
*version = (uint16_t)(rsf.fw_versions & 0xffff);
|
||||
|
||||
VBDEBUG(("TPM: RollbackFirmwareSetup %x %x %x\n", (int)rsf.fw_versions, (int)*key_version, (int)*version));
|
||||
|
||||
*version = rsf.fw_versions;
|
||||
VBDEBUG(("TPM: RollbackFirmwareSetup %x %x %x\n", (int)rsf.fw_versions));
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) {
|
||||
uint32_t RollbackFirmwareWrite(uint32_t version) {
|
||||
RollbackSpaceFirmware rsf;
|
||||
uint32_t new_versions = ((uint32_t)key_version << 16) | version;
|
||||
|
||||
VBDEBUG(("TPM: RollbackFirmwareWrite(%d, %d)\n", (int)key_version, (int)version));
|
||||
|
||||
RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
|
||||
VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions, (int)new_versions));
|
||||
rsf.fw_versions = new_versions;
|
||||
VBDEBUG(("TPM: RollbackFirmwareWrite %x --> %x\n", (int)rsf.fw_versions,
|
||||
(int)version));
|
||||
rsf.fw_versions = version;
|
||||
return WriteSpaceFirmware(&rsf);
|
||||
}
|
||||
|
||||
@@ -363,36 +356,27 @@ uint32_t RollbackKernelRecovery(int developer_mode) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) {
|
||||
uint32_t RollbackKernelRead(uint32_t* version) {
|
||||
if (g_rollback_recovery_mode) {
|
||||
*key_version = 0;
|
||||
*version = 0;
|
||||
} else {
|
||||
RollbackSpaceKernel rsk;
|
||||
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
||||
*key_version = (uint16_t)(rsk.kernel_versions >> 16);
|
||||
*version = (uint16_t)(rsk.kernel_versions & 0xffff);
|
||||
VBDEBUG(("TPM: RollbackKernelRead %x %x %x\n", (int)rsk.kernel_versions,
|
||||
(int)*key_version, (int)*version));
|
||||
*version = rsk.kernel_versions;
|
||||
VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
|
||||
}
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) {
|
||||
|
||||
VBDEBUG(("TPM: RollbackKernelWrite(%d, %d)\n", (int)key_version,
|
||||
(int)version));
|
||||
|
||||
uint32_t RollbackKernelWrite(uint32_t version) {
|
||||
if (g_rollback_recovery_mode) {
|
||||
return TPM_SUCCESS;
|
||||
} else {
|
||||
RollbackSpaceKernel rsk;
|
||||
uint32_t new_versions = ((uint32_t)key_version << 16) | version;
|
||||
|
||||
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
||||
VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
|
||||
(int)new_versions));
|
||||
rsk.kernel_versions = new_versions;
|
||||
(int)version));
|
||||
rsk.kernel_versions = version;
|
||||
return WriteSpaceKernel(&rsk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,10 +36,8 @@ int LoadFirmware(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;
|
||||
uint64_t lowest_key_version = 0xFFFF;
|
||||
uint64_t lowest_fw_version = 0xFFFF;
|
||||
uint32_t tpm_version = 0;
|
||||
uint64_t lowest_version = 0xFFFFFFFF;
|
||||
uint32_t status;
|
||||
int good_index = -1;
|
||||
int index;
|
||||
@@ -62,7 +60,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
|
||||
/* Initialize the TPM and read rollback indices. */
|
||||
status = RollbackFirmwareSetup(params->boot_flags & BOOT_FLAG_DEVELOPER,
|
||||
&tpm_key_version, &tpm_fw_version);
|
||||
&tpm_version);
|
||||
if (0 != status) {
|
||||
VBDEBUG(("Unable to setup TPM and read stored versions.\n"));
|
||||
return (status == TPM_E_MUST_REBOOT ?
|
||||
@@ -82,6 +80,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
VbFirmwarePreambleHeader* preamble;
|
||||
RSAPublicKey* data_key;
|
||||
uint64_t key_version;
|
||||
uint64_t combined_version;
|
||||
uint8_t* body_digest;
|
||||
|
||||
/* Verify the key block */
|
||||
@@ -99,7 +98,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
|
||||
/* Check for rollback of key version. */
|
||||
key_version = key_block->data_key.key_version;
|
||||
if (key_version < tpm_key_version) {
|
||||
if (key_version < (tpm_version >> 16)) {
|
||||
VBDEBUG(("Key rollback detected.\n"));
|
||||
continue;
|
||||
}
|
||||
@@ -123,22 +122,17 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
}
|
||||
|
||||
/* Check for rollback of firmware version. */
|
||||
if (key_version == tpm_key_version &&
|
||||
preamble->firmware_version < tpm_fw_version) {
|
||||
combined_version = ((key_version << 16) |
|
||||
(preamble->firmware_version & 0xFFFF));
|
||||
if (combined_version < tpm_version) {
|
||||
VBDEBUG(("Firmware version rollback detected.\n"));
|
||||
RSAPublicKeyFree(data_key);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for lowest key version from a valid header. */
|
||||
if (lowest_key_version > key_version) {
|
||||
lowest_key_version = key_version;
|
||||
lowest_fw_version = preamble->firmware_version;
|
||||
}
|
||||
else if (lowest_key_version == key_version &&
|
||||
lowest_fw_version > preamble->firmware_version) {
|
||||
lowest_fw_version = preamble->firmware_version;
|
||||
}
|
||||
if (lowest_version > combined_version)
|
||||
lowest_version = combined_version;
|
||||
|
||||
/* If we already have good firmware, no need to read another one;
|
||||
* we only needed to look at the versions to check for
|
||||
@@ -202,8 +196,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
* 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->firmware_version == tpm_fw_version)
|
||||
if (combined_version == tpm_version)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -216,12 +209,8 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
if (good_index >= 0) {
|
||||
|
||||
/* Update TPM if necessary */
|
||||
if ((lowest_key_version > tpm_key_version) ||
|
||||
(lowest_key_version == tpm_key_version &&
|
||||
lowest_fw_version > tpm_fw_version)) {
|
||||
|
||||
status = RollbackFirmwareWrite((uint16_t)lowest_key_version,
|
||||
(uint16_t)lowest_fw_version);
|
||||
if (lowest_version > tpm_version) {
|
||||
status = RollbackFirmwareWrite((uint32_t)lowest_version);
|
||||
if (0 != status) {
|
||||
VBDEBUG(("Unable to write stored versions.\n"));
|
||||
return (status == TPM_E_MUST_REBOOT ?
|
||||
|
||||
@@ -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 ?
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint16_t x, y;
|
||||
|
||||
/* cgptlib.h */
|
||||
GptInit(0);
|
||||
GptNextKernelEntry(0, 0, 0);
|
||||
@@ -29,12 +27,12 @@ int main(void)
|
||||
LoadKernel(0);
|
||||
|
||||
/* rollback_index.h */
|
||||
RollbackFirmwareSetup(0, &x, &y);
|
||||
RollbackFirmwareWrite(0, 0);
|
||||
RollbackFirmwareSetup(0, 0);
|
||||
RollbackFirmwareWrite(0);
|
||||
RollbackFirmwareLock();
|
||||
RollbackKernelRecovery(0);
|
||||
RollbackKernelRead(&x, &y);
|
||||
RollbackKernelWrite(0, 0);
|
||||
RollbackKernelRead(0);
|
||||
RollbackKernelWrite(0);
|
||||
RollbackKernelLock();
|
||||
|
||||
/* tlcl.h */
|
||||
|
||||
@@ -1 +1 @@
|
||||
char* VbootVersion = "VBOOv=38c0921e";
|
||||
char* VbootVersion = "VBOOv=16e190d8";
|
||||
|
||||
Reference in New Issue
Block a user