mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-24 16:57:21 +00:00
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:
@@ -204,9 +204,13 @@ typedef struct VbSharedDataHeader {
|
|||||||
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
|
uint8_t check_fw_b_result; /* Result of checking RW firmware B */
|
||||||
uint8_t firmware_index; /* Firmware index returned by
|
uint8_t firmware_index; /* Firmware index returned by
|
||||||
* LoadFirmware() or 0xFF if failure */
|
* 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_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
|
/* After read-only firmware which uses version 1 is released, any additional
|
||||||
* fields must be added below, and the struct version must be increased.
|
* fields must be added below, and the struct version must be increased.
|
||||||
* Before reading/writing those fields, make sure that the struct being
|
* Before reading/writing those fields, make sure that the struct being
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ uint32_t RollbackS3Resume(void);
|
|||||||
* mode. */
|
* mode. */
|
||||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version);
|
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 */
|
/* Write may be called if the versions change */
|
||||||
uint32_t RollbackFirmwareWrite(uint32_t version);
|
uint32_t RollbackFirmwareWrite(uint32_t version);
|
||||||
|
|
||||||
@@ -109,8 +114,7 @@ uint32_t RollbackFirmwareLock(void);
|
|||||||
* mode. */
|
* mode. */
|
||||||
uint32_t RollbackKernelRecovery(int developer_mode);
|
uint32_t RollbackKernelRecovery(int developer_mode);
|
||||||
|
|
||||||
/* Read and write may be called if not in developer mode. If called in
|
/* Read and write may be called to read and write the kernel version. */
|
||||||
* recovery mode, the effect is undefined. */
|
|
||||||
uint32_t RollbackKernelRead(uint32_t* version);
|
uint32_t RollbackKernelRead(uint32_t* version);
|
||||||
uint32_t RollbackKernelWrite(uint32_t version);
|
uint32_t RollbackKernelWrite(uint32_t version);
|
||||||
|
|
||||||
|
|||||||
@@ -301,6 +301,11 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
|||||||
return TPM_SUCCESS;
|
return TPM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t RollbackFirmwareRead(uint32_t* version) {
|
||||||
|
*version = 0;
|
||||||
|
return TPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RollbackFirmwareWrite(uint32_t version) {
|
uint32_t RollbackFirmwareWrite(uint32_t version) {
|
||||||
return TPM_SUCCESS;
|
return TPM_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -357,6 +362,16 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
|||||||
return TPM_SUCCESS;
|
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) {
|
uint32_t RollbackFirmwareWrite(uint32_t version) {
|
||||||
RollbackSpaceFirmware rsf;
|
RollbackSpaceFirmware rsf;
|
||||||
@@ -390,40 +405,32 @@ uint32_t RollbackKernelRecovery(int developer_mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RollbackKernelRead(uint32_t* version) {
|
uint32_t RollbackKernelRead(uint32_t* version) {
|
||||||
if (g_rollback_recovery_mode) {
|
RollbackSpaceKernel rsk;
|
||||||
*version = 0;
|
uint32_t perms;
|
||||||
} else {
|
|
||||||
RollbackSpaceKernel rsk;
|
|
||||||
uint32_t perms;
|
|
||||||
|
|
||||||
/* Read the kernel space and verify its permissions. If the kernel
|
/* Read the kernel space and verify its permissions. If the kernel
|
||||||
* space has the wrong permission, or it doesn't contain the right
|
* space has the wrong permission, or it doesn't contain the right
|
||||||
* identifier, we give up. This will need to be fixed by the
|
* identifier, we give up. This will need to be fixed by the
|
||||||
* recovery kernel. We have to worry about this because at any time
|
* recovery kernel. We have to worry about this because at any time
|
||||||
* (even with PP turned off) the TPM owner can remove and redefine a
|
* (even with PP turned off) the TPM owner can remove and redefine a
|
||||||
* PP-protected space (but not write to it). */
|
* PP-protected space (but not write to it). */
|
||||||
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
||||||
RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
|
RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms));
|
||||||
if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid)
|
if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid)
|
||||||
return TPM_E_CORRUPTED_STATE;
|
return TPM_E_CORRUPTED_STATE;
|
||||||
|
|
||||||
*version = rsk.kernel_versions;
|
*version = rsk.kernel_versions;
|
||||||
VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
|
VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions));
|
||||||
}
|
|
||||||
return TPM_SUCCESS;
|
return TPM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RollbackKernelWrite(uint32_t version) {
|
uint32_t RollbackKernelWrite(uint32_t version) {
|
||||||
if (g_rollback_recovery_mode) {
|
RollbackSpaceKernel rsk;
|
||||||
return TPM_SUCCESS;
|
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
||||||
} else {
|
VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
|
||||||
RollbackSpaceKernel rsk;
|
(int)version));
|
||||||
RETURN_ON_FAILURE(ReadSpaceKernel(&rsk));
|
rsk.kernel_versions = version;
|
||||||
VBDEBUG(("TPM: RollbackKernelWrite %x --> %x\n", (int)rsk.kernel_versions,
|
return WriteSpaceKernel(&rsk);
|
||||||
(int)version));
|
|
||||||
rsk.kernel_versions = version;
|
|
||||||
return WriteSpaceKernel(&rsk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RollbackKernelLock(void) {
|
uint32_t RollbackKernelLock(void) {
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
|||||||
goto LoadFirmwareExit;
|
goto LoadFirmwareExit;
|
||||||
}
|
}
|
||||||
shared->fw_version_tpm_start = tpm_version;
|
shared->fw_version_tpm_start = tpm_version;
|
||||||
|
shared->fw_version_tpm = tpm_version;
|
||||||
VBPERFEND("VB_TPMI");
|
VBPERFEND("VB_TPMI");
|
||||||
|
|
||||||
/* Read try-b count and decrement if necessary */
|
/* Read try-b count and decrement if necessary */
|
||||||
@@ -347,6 +348,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
|||||||
recovery = VBNV_RECOVERY_RO_TPM_ERROR;
|
recovery = VBNV_RECOVERY_RO_TPM_ERROR;
|
||||||
goto LoadFirmwareExit;
|
goto LoadFirmwareExit;
|
||||||
}
|
}
|
||||||
|
shared->fw_version_tpm = (uint32_t)lowest_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock firmware versions in TPM */
|
/* Lock firmware versions in TPM */
|
||||||
|
|||||||
@@ -232,6 +232,12 @@ int LoadKernel(LoadKernelParams* params) {
|
|||||||
/* Ignore return code, since we need to boot recovery mode to
|
/* Ignore return code, since we need to boot recovery mode to
|
||||||
* fix the TPM. */
|
* 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 {
|
} else {
|
||||||
/* Use the kernel subkey passed from LoadFirmware(). */
|
/* Use the kernel subkey passed from LoadFirmware(). */
|
||||||
kernel_subkey = &shared->kernel_subkey;
|
kernel_subkey = &shared->kernel_subkey;
|
||||||
@@ -247,6 +253,8 @@ int LoadKernel(LoadKernelParams* params) {
|
|||||||
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
|
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
|
||||||
goto LoadKernelExit;
|
goto LoadKernelExit;
|
||||||
}
|
}
|
||||||
|
if (shared)
|
||||||
|
shared->kernel_version_tpm = tpm_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -521,6 +529,8 @@ int LoadKernel(LoadKernelParams* params) {
|
|||||||
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
|
recovery = VBNV_RECOVERY_RW_TPM_ERROR;
|
||||||
goto LoadKernelExit;
|
goto LoadKernelExit;
|
||||||
}
|
}
|
||||||
|
if (shared)
|
||||||
|
shared->kernel_version_tpm = (uint32_t)lowest_version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ int main(void)
|
|||||||
/* rollback_index.h */
|
/* rollback_index.h */
|
||||||
RollbackS3Resume();
|
RollbackS3Resume();
|
||||||
RollbackFirmwareSetup(0, 0);
|
RollbackFirmwareSetup(0, 0);
|
||||||
|
RollbackFirmwareRead(0);
|
||||||
RollbackFirmwareWrite(0);
|
RollbackFirmwareWrite(0);
|
||||||
RollbackFirmwareLock();
|
RollbackFirmwareLock();
|
||||||
RollbackKernelRecovery(0);
|
RollbackKernelRecovery(0);
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ typedef enum VdatStringField {
|
|||||||
|
|
||||||
/* Fields that GetVdatInt() can get */
|
/* Fields that GetVdatInt() can get */
|
||||||
typedef enum VdatIntField {
|
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;
|
} VdatIntField;
|
||||||
|
|
||||||
|
|
||||||
@@ -670,7 +672,12 @@ int GetVdatInt(VdatIntField field) {
|
|||||||
case VDAT_INT_FLAGS:
|
case VDAT_INT_FLAGS:
|
||||||
value = (int)sh->flags;
|
value = (int)sh->flags;
|
||||||
break;
|
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);
|
Free(ab);
|
||||||
@@ -747,6 +754,10 @@ int VbGetSystemPropertyInt(const char* name) {
|
|||||||
value = VbGetCrosDebug();
|
value = VbGetCrosDebug();
|
||||||
} else if (!strcasecmp(name,"vdat_flags")) {
|
} else if (!strcasecmp(name,"vdat_flags")) {
|
||||||
value = GetVdatInt(VDAT_INT_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;
|
return value;
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ const Param sys_param_list[] = {
|
|||||||
{"tried_fwb", 0, "Tried firmware B before A this boot"},
|
{"tried_fwb", 0, "Tried firmware B before A this boot"},
|
||||||
{"cros_debug", 0, "OS should allow debug features"},
|
{"cros_debug", 0, "OS should allow debug features"},
|
||||||
{"vdat_flags", 0, "Flags from VbSharedData", "0x%08x"},
|
{"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 */
|
/* Read-only strings */
|
||||||
{"hwid", IS_STRING, "Hardware ID"},
|
{"hwid", IS_STRING, "Hardware ID"},
|
||||||
{"fwid", IS_STRING, "Active firmware ID"},
|
{"fwid", IS_STRING, "Active firmware ID"},
|
||||||
|
|||||||
Reference in New Issue
Block a user