[coreboot-gerrit] Patch set updated for coreboot: TPM: Add option to read PCRs after TPM initialization

Georg Wicherski (gw@oxff.net) gerrit at coreboot.org
Mon Mar 14 13:16:44 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 80eb817fb874d521d382e03370b179c4156bc054
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).
    
    Add new Kconfig TPM_READ_INIT_PCRS and tlcl_pcr_read depending on the
    former (which is then invoked in init_tpm).
    
    Change-Id: I79e7fdc97d500228aa574fe344ad7ac1cb0dfe64
    Signed-off-by: Georg Wicherski <gw at oxff.net>
---
 src/drivers/tpm/lpc/Kconfig | 11 +++++++++++
 src/include/tpm/tss.h       |  5 +++++
 src/lib/tpm/tspi.c          | 35 +++++++++++++++++++++++++++++++++++
 src/lib/tpm/tss.c           | 23 ++++++++++++++++++++---
 4 files changed, 71 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..0d9c6aa 100644
--- a/src/lib/tpm/tspi.c
+++ b/src/lib/tpm/tspi.c
@@ -19,8 +19,40 @@
 #include <reset.h>
 
 #include <tpm/tss.h>
+#define TPM_PCR_DIGEST_LENGTH 20
 #include <tpm/tspi.h>
 
+static inline void _debug_init_pcrs(void)
+{
+	uint32_t result;
+	int pcr_index;
+	uint8_t digest[TPM_PCR_DIGEST_LENGTH];
+
+	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 < TPM_PCR_DIGEST_LENGTH;
+				++digest_offset) {
+			printk(BIOS_SPEW, "%02x%c",
+				digest[digest_offset],
+				digest_offset < TPM_PCR_DIGEST_LENGTH - 1 ?
+				':' : '\n');
+		}
+	}
+}
+
 void init_tpm(int s3resume)
 {
 	u32 result = 0;
@@ -76,6 +108,9 @@ void init_tpm(int s3resume)
 	}
 
 	if (result == TPM_SUCCESS) {
+		if (IS_ENABLED(CONFIG_TPM_READ_INIT_PCRS))
+			_debug_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..8f38504 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,23 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
 
 	if (out_digest)
 		memcpy(out_digest, response + kTpmResponseHeaderLength,
-		       kPcrDigestLength);
+				kPcrDigestLength);
+	return result;
+}
+
+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;
 }



More information about the coreboot-gerrit mailing list