diff options
author | Randall Spangler <rspangler@chromium.org> | 2011-03-17 17:58:56 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2011-03-17 17:58:56 -0700 |
commit | 5ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472 (patch) | |
tree | b92352d8dfb4e721ec9127efdb142e77c182187b /firmware | |
parent | f4ba19d81d4fefa0dba4efbdd57dc863138fde3a (diff) | |
download | vboot-5ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472.tar.gz |
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
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/include/vboot_struct.h | 6 | ||||
-rw-r--r-- | firmware/lib/include/rollback_index.h | 8 | ||||
-rw-r--r-- | firmware/lib/rollback_index.c | 67 | ||||
-rw-r--r-- | firmware/lib/vboot_firmware.c | 2 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 10 | ||||
-rw-r--r-- | firmware/linktest/main.c | 1 |
6 files changed, 61 insertions, 33 deletions
diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h index f4364274..7cf88032 100644 --- a/firmware/include/vboot_struct.h +++ b/firmware/include/vboot_struct.h @@ -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 diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h index 0e630dbb..7db85150 100644 --- a/firmware/lib/include/rollback_index.h +++ b/firmware/lib/include/rollback_index.h @@ -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); diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c index 9442b779..697bd0e7 100644 --- a/firmware/lib/rollback_index.c +++ b/firmware/lib/rollback_index.c @@ -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,40 +405,32 @@ 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; - - /* Read the kernel space and verify its permissions. If the kernel - * space has the wrong permission, or it doesn't contain the right - * identifier, we give up. This will need to be fixed by the - * 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 - * PP-protected space (but not write to it). */ - RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); - RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); - if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid) - return TPM_E_CORRUPTED_STATE; - - *version = rsk.kernel_versions; - VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions)); - } + RollbackSpaceKernel rsk; + uint32_t perms; + + /* Read the kernel space and verify its permissions. If the kernel + * space has the wrong permission, or it doesn't contain the right + * identifier, we give up. This will need to be fixed by the + * 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 + * PP-protected space (but not write to it). */ + RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); + RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); + if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid) + return TPM_E_CORRUPTED_STATE; + + *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); - } + 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) { diff --git a/firmware/lib/vboot_firmware.c b/firmware/lib/vboot_firmware.c index dd006f3a..6c895e92 100644 --- a/firmware/lib/vboot_firmware.c +++ b/firmware/lib/vboot_firmware.c @@ -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 */ diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index e50fd0f6..204874f6 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -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; } } diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c index 16c4bf50..a3ed21a5 100644 --- a/firmware/linktest/main.c +++ b/firmware/linktest/main.c @@ -31,6 +31,7 @@ int main(void) /* rollback_index.h */ RollbackS3Resume(); RollbackFirmwareSetup(0, 0); + RollbackFirmwareRead(0); RollbackFirmwareWrite(0); RollbackFirmwareLock(); RollbackKernelRecovery(0); |