summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-01-09 14:17:40 -0800
committerLuigi Semenzato <semenzato@chromium.org>2012-01-09 15:00:52 -0800
commit946370d012a809bba833ff9d37fe0ce86af09860 (patch)
treeeffbf117a9d986d3d9308320ca24da3e9deb4014
parent93a892ce8be7eb906521702f88e6183d26f2a435 (diff)
downloadvboot-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.h5
-rw-r--r--firmware/include/tss_constants.h1
-rw-r--r--firmware/lib/tpm_lite/include/tlcl_structures.h6
-rw-r--r--firmware/lib/tpm_lite/tlcl.c22
-rw-r--r--utility/tlcl_generator.c9
-rw-r--r--utility/tpmc.c25
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",