Add TPM version checking

Change-Id: Ic32b7bcf0bc5501e21dc84e79419a256d9b0d095

R=semenzato@chromium.org,reinauer@chromium.org
BUG=chrome-os-partner:2832
TEST=manual

crossystem tpm_fwver tpm_kernver
On a debug system, this will return 0x00010001 0x00010001

Review URL: http://codereview.chromium.org/6685075
This commit is contained in:
Randall Spangler
2011-03-17 17:58:56 -07:00
parent f4ba19d81d
commit 5ac39bfff0
8 changed files with 74 additions and 33 deletions

View File

@@ -204,9 +204,13 @@ typedef struct VbSharedDataHeader {
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
uint8_t firmware_index; /* Firmware index returned by
* LoadFirmware() or 0xFF if failure */
uint32_t fw_version_tpm_start; /* Firmware TPM version at start */
uint32_t fw_version_tpm_start; /* Firmware TPM version at start of
* LoadFirmware() */
uint32_t fw_version_lowest; /* Firmware lowest version found */
uint32_t fw_version_tpm; /* Current firmware version in TPM */
uint32_t kernel_version_tpm; /* Current kernel version in TPM */
/* After read-only firmware which uses version 1 is released, any additional
* fields must be added below, and the struct version must be increased.
* Before reading/writing those fields, make sure that the struct being

View File

@@ -94,6 +94,11 @@ uint32_t RollbackS3Resume(void);
* mode. */
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version);
/* Read may be called to get the version. This is not necessary in
* the normal boot path, because RollbackFirmwareSetup() provides the
* same information. It may be used in the recovery path. */
uint32_t RollbackFirmwareRead(uint32_t* version);
/* Write may be called if the versions change */
uint32_t RollbackFirmwareWrite(uint32_t version);
@@ -109,8 +114,7 @@ uint32_t RollbackFirmwareLock(void);
* mode. */
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. */
/* Read and write may be called to read and write the kernel version. */
uint32_t RollbackKernelRead(uint32_t* version);
uint32_t RollbackKernelWrite(uint32_t version);

View File

@@ -301,6 +301,11 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
return TPM_SUCCESS;
}
uint32_t RollbackFirmwareRead(uint32_t* version) {
*version = 0;
return TPM_SUCCESS;
}
uint32_t RollbackFirmwareWrite(uint32_t version) {
return TPM_SUCCESS;
}
@@ -357,6 +362,16 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
return TPM_SUCCESS;
}
uint32_t RollbackFirmwareRead(uint32_t* version) {
RollbackSpaceFirmware rsf;
RETURN_ON_FAILURE(ReadSpaceFirmware(&rsf));
VBDEBUG(("TPM: RollbackFirmwareRead %x --> %x\n", (int)rsf.fw_versions,
(int)version));
*version = rsf.fw_versions;
VBDEBUG(("TPM: RollbackFirmwareRead %x\n", (int)rsf.fw_versions));
return TPM_SUCCESS;
}
uint32_t RollbackFirmwareWrite(uint32_t version) {
RollbackSpaceFirmware rsf;
@@ -390,9 +405,6 @@ uint32_t RollbackKernelRecovery(int developer_mode) {
}
uint32_t RollbackKernelRead(uint32_t* version) {
if (g_rollback_recovery_mode) {
*version = 0;
} else {
RollbackSpaceKernel rsk;
uint32_t perms;
@@ -409,21 +421,16 @@ uint32_t RollbackKernelRead(uint32_t* version) {
*version = rsk.kernel_versions;
VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
}
return TPM_SUCCESS;
}
uint32_t RollbackKernelWrite(uint32_t version) {
if (g_rollback_recovery_mode) {
return TPM_SUCCESS;
} else {
RollbackSpaceKernel rsk;
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
(int)version));
rsk.kernel_versions = version;
return WriteSpaceKernel(&rsk);
}
}
uint32_t RollbackKernelLock(void) {

View File

@@ -125,6 +125,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
goto LoadFirmwareExit;
}
shared->fw_version_tpm_start = tpm_version;
shared->fw_version_tpm = tpm_version;
VBPERFEND("VB_TPMI");
/* Read try-b count and decrement if necessary */
@@ -347,6 +348,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
recovery = VBNV_RECOVERY_RO_TPM_ERROR;
goto LoadFirmwareExit;
}
shared->fw_version_tpm = (uint32_t)lowest_version;
}
/* Lock firmware versions in TPM */

View File

@@ -232,6 +232,12 @@ int LoadKernel(LoadKernelParams* params) {
/* Ignore return code, since we need to boot recovery mode to
* fix the TPM. */
}
/* Read the key indices from the TPM; ignore any errors */
if (shared) {
RollbackFirmwareRead(&shared->fw_version_tpm);
RollbackKernelRead(&shared->kernel_version_tpm);
}
} else {
/* Use the kernel subkey passed from LoadFirmware(). */
kernel_subkey = &shared->kernel_subkey;
@@ -247,6 +253,8 @@ int LoadKernel(LoadKernelParams* params) {
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
goto LoadKernelExit;
}
if (shared)
shared->kernel_version_tpm = tpm_version;
}
do {
@@ -521,6 +529,8 @@ int LoadKernel(LoadKernelParams* params) {
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
goto LoadKernelExit;
}
if (shared)
shared->kernel_version_tpm = (uint32_t)lowest_version;
}
}

View File

@@ -31,6 +31,7 @@ int main(void)
/* rollback_index.h */
RollbackS3Resume();
RollbackFirmwareSetup(0, 0);
RollbackFirmwareRead(0);
RollbackFirmwareWrite(0);
RollbackFirmwareLock();
RollbackKernelRecovery(0);

View File

@@ -101,7 +101,9 @@ typedef enum VdatStringField {
/* Fields that GetVdatInt() can get */
typedef enum VdatIntField {
VDAT_INT_FLAGS = 0 /* Flags */
VDAT_INT_FLAGS = 0, /* Flags */
VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */
VDAT_INT_KERNEL_VERSION_TPM /* Current kernel version in TPM */
} VdatIntField;
@@ -670,7 +672,12 @@ int GetVdatInt(VdatIntField field) {
case VDAT_INT_FLAGS:
value = (int)sh->flags;
break;
case VDAT_INT_FW_VERSION_TPM:
value = (int)sh->fw_version_tpm;
break;
case VDAT_INT_KERNEL_VERSION_TPM:
value = (int)sh->kernel_version_tpm;
break;
}
Free(ab);
@@ -747,6 +754,10 @@ int VbGetSystemPropertyInt(const char* name) {
value = VbGetCrosDebug();
} else if (!strcasecmp(name,"vdat_flags")) {
value = GetVdatInt(VDAT_INT_FLAGS);
} else if (!strcasecmp(name,"tpm_fwver")) {
value = GetVdatInt(VDAT_INT_FW_VERSION_TPM);
} else if (!strcasecmp(name,"tpm_kernver")) {
value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM);
}
return value;

View File

@@ -41,6 +41,8 @@ const Param sys_param_list[] = {
{"tried_fwb", 0, "Tried firmware B before A this boot"},
{"cros_debug", 0, "OS should allow debug features"},
{"vdat_flags", 0, "Flags from VbSharedData", "0x%08x"},
{"tpm_fwver", 0, "Firmware version stored in TPM", "0x%08x"},
{"tpm_kernver", 0, "Kernel version stored in TPM", "0x%08x"},
/* Read-only strings */
{"hwid", IS_STRING, "Hardware ID"},
{"fwid", IS_STRING, "Active firmware ID"},