diff options
author | Kees Cook <keescook@chromium.org> | 2012-01-09 14:17:40 -0800 |
---|---|---|
committer | Luigi Semenzato <semenzato@chromium.org> | 2012-01-09 15:00:52 -0800 |
commit | 946370d012a809bba833ff9d37fe0ce86af09860 (patch) | |
tree | effbf117a9d986d3d9308320ca24da3e9deb4014 | |
parent | 93a892ce8be7eb906521702f88e6183d26f2a435 (diff) | |
download | vboot-946370d012a809bba833ff9d37fe0ce86af09860.tar.gz |
tpmc: add PCR reading function
Add ability to report a single PCR value via the tpmc utility. Using
/sys/devices/platform/tpm_tis/pcrs is too slow, since it reads all
PCRs before returning. Anything wanting to read PCR0 on a time-critical
path needs maximum speed.
BUG=chromium-os:22172
TEST=install and test x86-alex.
Change-Id: I2d450961d33fa314d54b909135a74aa756279ec6
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/13891
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
-rw-r--r-- | firmware/include/tlcl.h | 5 | ||||
-rw-r--r-- | firmware/include/tss_constants.h | 1 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/include/tlcl_structures.h | 6 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 22 | ||||
-rw-r--r-- | utility/tlcl_generator.c | 9 | ||||
-rw-r--r-- | utility/tpmc.c | 25 |
6 files changed, 68 insertions, 0 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h index cb7ea9ab..6f0db1b6 100644 --- a/firmware/include/tlcl.h +++ b/firmware/include/tlcl.h @@ -68,6 +68,11 @@ uint32_t TlclWrite(uint32_t index, const void* data, uint32_t length); */ uint32_t TlclRead(uint32_t index, void* data, uint32_t length); +/* Reads PCR at [index] into [data]. [length] must be TPM_PCR_DIGEST or + * larger. The TPM error code is returned. + */ +uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length); + /* Write-locks space at [index]. The TPM error code is returned. */ uint32_t TlclWriteLock(uint32_t index); diff --git a/firmware/include/tss_constants.h b/firmware/include/tss_constants.h index 42de46f3..68a9c6ff 100644 --- a/firmware/include/tss_constants.h +++ b/firmware/include/tss_constants.h @@ -14,6 +14,7 @@ #define TPM_MAX_COMMAND_SIZE 4096 #define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */ #define TPM_PUBEK_SIZE 256 +#define TPM_PCR_DIGEST 20 #define TPM_E_NON_FATAL 0x800 diff --git a/firmware/lib/tpm_lite/include/tlcl_structures.h b/firmware/lib/tpm_lite/include/tlcl_structures.h index a53e2baa..e0a7a46b 100644 --- a/firmware/lib/tpm_lite/include/tlcl_structures.h +++ b/firmware/lib/tpm_lite/include/tlcl_structures.h @@ -94,6 +94,12 @@ const struct s_tpm_ppassert_cmd{ } tpm_ppassert_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x8, }, }; +const struct s_tpm_pcr_read_cmd{ + uint8_t buffer[14]; + uint16_t pcrNum; +} tpm_pcr_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, }, +10, }; + const struct s_tpm_nv_read_cmd{ uint8_t buffer[22]; uint16_t index; diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index fc820b55..42739904 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -214,6 +214,28 @@ uint32_t TlclRead(uint32_t index, void* data, uint32_t length) { return result; } +uint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length) { + struct s_tpm_nv_read_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t result_length; + uint32_t result; + + VBDEBUG(("TPM: TlclPCRRead(0x%x, %d)\n", index, length)); + if (length < kPcrDigestLength) { + return TPM_E_IOERROR; + } + Memcpy(&cmd, &tpm_pcr_read_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_pcr_read_cmd.pcrNum, index); + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result == TPM_SUCCESS) { + uint8_t* pcr_read_cursor = response + kTpmResponseHeaderLength; + Memcpy(data, pcr_read_cursor, kPcrDigestLength); + } + + return result; +} + uint32_t TlclWriteLock(uint32_t index) { VBDEBUG(("TPM: Write lock 0x%x\n", index)); return TlclWrite(index, NULL, 0); diff --git a/utility/tlcl_generator.c b/utility/tlcl_generator.c index 86b7e4ed..f905784f 100644 --- a/utility/tlcl_generator.c +++ b/utility/tlcl_generator.c @@ -170,6 +170,14 @@ Command* BuildReadCommand(void) { return cmd; } +Command* BuildPCRReadCommand(void) { + int size = kTpmRequestHeaderLength + sizeof(uint32_t); + Command* cmd = newCommand(TPM_ORD_PcrRead, size); + cmd->name = "tpm_pcr_read_cmd"; + AddVisibleField(cmd, "pcrNum", kTpmRequestHeaderLength); + return cmd; +} + Command* BuildPPAssertCommand(void) { int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE); Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size); @@ -454,6 +462,7 @@ Command* (*builders[])(void) = { BuildDefineSpaceCommand, BuildWriteCommand, BuildReadCommand, + BuildPCRReadCommand, BuildPPAssertCommand, BuildPPEnableCommand, BuildPPLockCommand, diff --git a/utility/tpmc.c b/utility/tpmc.c index 0b89677c..d8fb07a5 100644 --- a/utility/tpmc.c +++ b/utility/tpmc.c @@ -160,6 +160,29 @@ static uint32_t HandlerWrite(void) { return TlclWrite(index, value, size); } +static uint32_t HandlerPCRRead(void) { + uint32_t index; + uint8_t value[TPM_PCR_DIGEST]; + uint32_t result; + int i; + if (nargs != 3) { + fprintf(stderr, "usage: tpmc pcrread <index>\n"); + exit(OTHER_ERROR); + } + if (HexStringToUint32(args[2], &index) != 0) { + fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n"); + exit(OTHER_ERROR); + } + result = TlclPCRRead(index, value, sizeof(value)); + if (result == 0) { + for (i = 0; i < TPM_PCR_DIGEST; i++) { + printf("%02x", value[i]); + } + printf("\n"); + } + return result; +} + static uint32_t HandlerRead(void) { uint32_t index, size; uint8_t value[4096]; @@ -283,6 +306,8 @@ command_record command_table[] = { HandlerWrite }, { "read", "read", "read from a space (read <index> <size>)", HandlerRead }, + { "pcrread", "pcr", "read from a PCR (pcrread <index>)", + HandlerPCRRead }, { "getpermissions", "getp", "print space permissions (getp <index>)", HandlerGetPermissions }, { "getpermanentflags", "getpf", "print all permanent flags", |