[coreboot-gerrit] New patch to review for coreboot: TPM: Add option to read PCRs after TPM initialization.

Georg Wicherski (gw@oxff.net) gerrit at coreboot.org
Wed Mar 9 17:25:16 CET 2016


Georg Wicherski (gw at oxff.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14009

-gerrit

commit 8c1bf841516352ae2dbf1822b73fd74cf7db29fd
Author: Georg Wicherski <gw at oxff.net>
Date:   Wed Mar 9 17:21:31 2016 +0100

    TPM: Add option to read PCRs after TPM initialization.
    
    Coreboot may be used on platforms using "Measured Boot". This change
    adds an option to read and print all PCRs right after initialization for
    identifying "Measured Boot" on a mainboard and determining the resulting
    initial PCR stage (depending on the bootblock).
    
    This works as expected on my Auron Paine, which apparently does not
    have "Measured Boot" and reports PCR contents as defined in the
    TPM TIS 1.2 (0s and -1s).
    
    Adds new Kconfig TPM_READ_INIT_PCRS and tlcl_pcr_read depending on the
    former (which is then invoked in init_tpm).
    
    Change-Id: I79e7fdc97d500228aa574fe344ad7ac1cb0dfe64
---
 src/drivers/tpm/lpc/Kconfig | 11 +++++++++++
 src/include/tpm/tss.h       |  5 +++++
 src/lib/tpm/tspi.c          | 29 +++++++++++++++++++++++++++++
 src/lib/tpm/tss.c           | 25 ++++++++++++++++++++++---
 4 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/src/drivers/tpm/lpc/Kconfig b/src/drivers/tpm/lpc/Kconfig
index e377e99..ec17782 100644
--- a/src/drivers/tpm/lpc/Kconfig
+++ b/src/drivers/tpm/lpc/Kconfig
@@ -13,6 +13,17 @@ config LPC_TPM
 
 	  If unsure, say N.
 
+config TPM_READ_INIT_PCRS
+	bool "Read PCR values after initialization"
+	depends on LPC_TPM
+	default n
+	help
+	  Read (and print) initial PCR values at end of TPM initialization.
+	  This is useful for identifying "Measured Boot" and verifying that
+	  the TPM is adhering to TPM TIS 1.2 PCR initial values.
+
+	  If unsure, say N.
+
 config TPM_TIS_BASE_ADDRESS
 	hex
 	default 0xfed40000
diff --git a/src/include/tpm/tss.h b/src/include/tpm/tss.h
index 04ad9b3..b940e9c 100644
--- a/src/include/tpm/tss.h
+++ b/src/include/tpm/tss.h
@@ -129,6 +129,11 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
 		uint8_t *out_digest);
 
 /**
+ * Read current PCR digest
+ */
+uint32_t tlcl_pcr_read(int pcr_num, uint8_t *out_digest);
+
+/**
  * Get the entire set of permanent flags.
  */
 uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
diff --git a/src/lib/tpm/tspi.c b/src/lib/tpm/tspi.c
index 0114af8..74142d1 100644
--- a/src/lib/tpm/tspi.c
+++ b/src/lib/tpm/tspi.c
@@ -19,6 +19,7 @@
 #include <reset.h>
 
 #include <tpm/tss.h>
+#define kPcrDigestLength 20
 #include <tpm/tspi.h>
 
 void init_tpm(int s3resume)
@@ -76,6 +77,34 @@ void init_tpm(int s3resume)
 	}
 
 	if (result == TPM_SUCCESS) {
+#if CONFIG_TPM_READ_INIT_PCRS
+		int pcr_index;
+		uint8_t digest[kPcrDigestLength];
+
+		for (pcr_index = 0; pcr_index < 24; ++pcr_index) {
+			int digest_offset;
+
+			result = tlcl_pcr_read(pcr_index, digest);
+
+			if (result != TPM_SUCCESS) {
+				printk(BIOS_DEBUG,
+					"TPM: reading PCR %i failed\n",
+					pcr_index);
+				continue;
+			}
+
+			printk(BIOS_SPEW, "TPM: PCR %i value is ", pcr_index);
+			for (digest_offset = 0;
+					digest_offset < kPcrDigestLength;
+					++digest_offset) {
+				printk(BIOS_SPEW, "%02x%c",
+					digest[digest_offset],
+					digest_offset < kPcrDigestLength - 1 ?
+						':' : '\n');
+			}
+		}
+#endif /* CONFIG_TPM_READ_INIT_PCRS */
+
 		printk(BIOS_SPEW, "TPM: OK.\n");
 		return;
 	}
diff --git a/src/lib/tpm/tss.c b/src/lib/tpm/tss.c
index a22aa15..ecb3745 100644
--- a/src/lib/tpm/tss.c
+++ b/src/lib/tpm/tss.c
@@ -116,7 +116,7 @@ return result;
 uint32_t tlcl_send_receive(const uint8_t *request, uint8_t *response,
 		int max_length) {
 	uint32_t result = tlcl_send_receive_no_retry(request, response,
-						     max_length);
+							 max_length);
 	/* If the command fails because the self test has not completed, try it
 	 * again after attempting to ensure that the self test has completed. */
 	if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) {
@@ -303,7 +303,7 @@ uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags)
 	from_tpm_uint32(response + kTpmResponseHeaderLength, &size);
 	assert(size == sizeof(TPM_PERMANENT_FLAGS));
 	memcpy(pflags, response + kTpmResponseHeaderLength + sizeof(size),
-	       sizeof(TPM_PERMANENT_FLAGS));
+		   sizeof(TPM_PERMANENT_FLAGS));
 	return result;
 }
 
@@ -351,6 +351,25 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
 
 	if (out_digest)
 		memcpy(out_digest, response + kTpmResponseHeaderLength,
-		       kPcrDigestLength);
+			   kPcrDigestLength);
 	return result;
 }
+
+#if CONFIG_TPM_READ_INIT_PCRS
+uint32_t tlcl_pcr_read(int pcr_num, uint8_t *out_digest)
+{
+	struct s_tpm_pcr_read_cmd cmd;
+	uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+	uint32_t result;
+
+	memcpy(&cmd, &tpm_pcr_read_cmd, sizeof(cmd));
+	to_tpm_uint32(cmd.buffer + tpm_pcr_read_cmd.pcrNum, pcr_num);
+
+	result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+	if (result == TPM_SUCCESS)
+		memcpy(out_digest, response + kTpmResponseHeaderLength,
+				kPcrDigestLength);
+
+	return result;
+}
+#endif /* CONFIG_TPM_READ_INIT_PCRS */



More information about the coreboot-gerrit mailing list