[Skiboot] [PATCH v2 30/31] libstb/tpm_chip: add tpm_extendl()

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Wed Sep 28 18:01:29 AEST 2016


This adds the tpm_extendl() function to tpm_chip interface

For each TPM device, tpm_extendl() extends the sha1 and sha256 digests
provided to the indicated PCR and also records an event for the same PCR
in the event log.

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 libstb/status_codes.h |   4 ++
 libstb/tpm_chip.c     | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libstb/tpm_chip.h     |  26 ++++++++++++
 3 files changed, 142 insertions(+)

diff --git a/libstb/status_codes.h b/libstb/status_codes.h
index 1637e9f..5fd9757 100644
--- a/libstb/status_codes.h
+++ b/libstb/status_codes.h
@@ -25,6 +25,10 @@
 /* secure boot */
 #define STB_VERIFY_FAILED  		-100
 
+/* trusted boot */
+#define STB_EVENTLOG_FAILED	-200
+#define STB_PCR_EXTEND_FAILED	-201
+
 /* TPM */
 #define STB_TPM_OVERFLOW	-300
 #define STB_TPM_TIMEOUT	-301
diff --git a/libstb/tpm_chip.c b/libstb/tpm_chip.c
index 91efa3a..0002f7f 100644
--- a/libstb/tpm_chip.c
+++ b/libstb/tpm_chip.c
@@ -22,9 +22,48 @@
 #include "container.h"
 #include "tpm_chip.h"
 #include "drivers/tpm_i2c_nuvoton.h"
+#include "tss/trustedbootCmds.H"
+
+/* For debugging only */
+//#define STB_DEBUG
 
 static struct list_head tpm_list = LIST_HEAD_INIT(tpm_list);
 
+#ifdef STB_DEBUG
+static void tpm_print_pcr(struct tpm_chip *tpm, TPM_Pcr pcr, TPM_Alg_Id alg,
+			  size_t size)
+{
+	int rc;
+	uint8_t digest[TPM_ALG_SHA256_SIZE];
+
+	memset(digest, 0, size);
+
+	rc = tpmCmdPcrRead(tpm, pcr, alg, digest, size);
+	if (rc) {
+		/**
+		 * @fwts-label STBPCRReadFailed¬
+		 * @fwts-advice STB_DEBUG should not be enabled
+		 * in production. PCR read operation failed.
+		 * This TSS implementation is part of hostboot,
+		 * but the source code is shared with skiboot.
+		 * 1) The hostboot TSS may have been updated.
+		 * 2) This may be caused by the short I2C
+		 * timeout and can be fixed by increasing the
+		 * timeout. Otherwise this indicates a bug in
+		 * the TSS or the TPM device driver. Each one
+		 * has local debug macros that can help.
+		 */
+		prlog(PR_ERR, "STB: tpmCmdPcrRead() failed: "
+		      "tpm%d, alg=%x, pcr%d, rc=%d\n",
+		      tpm->id, alg, pcr, rc);
+	} else {
+		prlog(PR_NOTICE,"STB: print pcr-read: tpm%d alg=%x pcr%d\n",
+		      tpm->id, alg, pcr);
+		stb_print_data(digest, size);
+	}
+}
+#endif
+
 int tpm_register_chip(struct dt_node *node, struct tpm_dev *dev,
 		       struct tpm_driver *driver)
 {
@@ -175,6 +214,79 @@ void tpm_cleanup(void)
 	list_head_init(&tpm_list);
 }
 
+int tpm_extendl(TPM_Pcr pcr,
+		TPM_Alg_Id alg1, uint8_t* digest1, size_t size1,
+		TPM_Alg_Id alg2, uint8_t* digest2, size_t size2,
+		uint32_t event_type, const char* event_msg)
+{
+	int rc;
+	TCG_PCR_EVENT2 event;
+	struct tpm_chip *tpm = NULL;
+
+	rc = 0;
+
+	list_for_each(&tpm_list, tpm, link) {
+		if (!tpm->enabled)
+			continue;
+		event = TpmLogMgr_genLogEventPcrExtend(pcr, alg1, digest1, size1,
+						       alg2, digest2, size2,
+						       event_type, event_msg);
+		/* eventlog recording */
+		rc = TpmLogMgr_addEvent(&tpm->logmgr, &event);
+		if (rc) {
+			/**
+			 * @fwts-label STBAddEventFailed
+			 * @fwts-advice TpmLogMgr failed to add a new event to the event
+			 * log. TpmLogMgr is part of hostboot, but the source code is
+			 * shared with skiboot. 1) The hostboot TpmLogMgr code may have
+			 * been updated. 2) Check that max event log size was not
+			 * reached and log marshall executed with no error. Enabling the
+			 * trace routines in trustedbootUtils.H may help.
+			 */
+			prlog(PR_ERR, "TPM: %s -> elog%d FAILED: pcr%d et=%x rc=%d\n",
+			      event_msg, tpm->id, pcr, event_type, rc);
+			rc = STB_EVENTLOG_FAILED;
+			goto error;
+		}
+#ifdef STB_DEBUG
+		prlog(PR_NOTICE, "TPM: %s -> elog%d: pcr%d et=%x ls=%d\n",
+		      event_msg, tpm->id, pcr, event_type, tpm->logmgr.logSize);
+		tpm_print_pcr(tpm, pcr, alg1, size1);
+		tpm_print_pcr(tpm, pcr, alg2, size2);
+#endif
+		/* extend pcr of both sha1 and sha256 banks*/
+		rc = tpmCmdPcrExtend2Hash(tpm, pcr,
+					  alg1, digest1, size1,
+					  alg2, digest2, size2);
+		if (rc) {
+			/**
+			 * @fwts-label STBPCRExtendFailed
+			 * @fwts-advice PCR extend operation failed. This TSS
+			 * implementation is part of hostboot, but the source code is
+			 * shared with skiboot. 1) The hostboot TSS may have been
+			 * updated. 2) This may be caused by the short I2C timeout and
+			 * can be fixed by increasing the timeout.
+			 * Otherwise this indicates a bug in the TSS or the TPM
+			 * device driver. Each one has local debug macros that can help.
+			 */
+			prlog(PR_ERR, "TPM: %s -> tpm%d FAILED: pcr%d rc=%d\n",
+			      event_msg, tpm->id, pcr, rc);
+			rc = STB_PCR_EXTEND_FAILED;
+			goto error;
+		}
+#ifdef STB_DEBUG
+		prlog(PR_NOTICE, "TPM: %s -> tpm%d: pcr%d\n", event_msg,
+		      tpm->id, pcr);
+		tpm_print_pcr(tpm, pcr, alg1, size1);
+		tpm_print_pcr(tpm, pcr, alg2, size2);
+#endif
+	}
+	return rc;
+error:
+	tpm->enabled = false;
+	return rc;
+}
+
 void tpm_add_status_property(void) {
 	struct tpm_chip *tpm;
 	list_for_each(&tpm_list, tpm, link) {
diff --git a/libstb/tpm_chip.h b/libstb/tpm_chip.h
index b8f536c..d7363e7 100644
--- a/libstb/tpm_chip.h
+++ b/libstb/tpm_chip.h
@@ -20,6 +20,7 @@
 #include <device.h>
 
 #include "tss/tpmLogMgr.H"
+#include "tss/trustedTypes.H"
 
 struct tpm_dev {
 
@@ -73,6 +74,31 @@ typedef struct tpm_chip TpmTarget;
 extern int tpm_register_chip(struct dt_node *node, struct tpm_dev *dev,
 			     struct tpm_driver *driver);
 
+/*
+ * tpm_extendl - For each TPM device, this extends the sha1 and sha 256 digests
+ * to the indicated PCR and also records an event for the same PCR
+ * in the event log
+ * This calls a TSS extend function that supports multibank. Both sha1 and
+ * sha256 digests are extended in a single operation sent to the TPM device.
+ *
+ * @pcr: PCR number to be extended and recorded in the event log. The same PCR
+ * number is extende for both sha1 and sha256 banks.
+ * @alg1: SHA algorithm of digest1. Either TPM_ALG_SHA1 or TPM_ALG_SHA256
+ * @digest1: digest1 buffer
+ * @size1: size of digest1. Either TPM_ALG_SHA1_SIZE or TPM_ALG_SHA256_SIZE
+ * @alg2: SHA algorithm of digest2. Either TPM_ALG_SHA1 or TPM_ALG_SHA256
+ * @digest2: digest2 buffer
+ * @size2: size of digest2. Either TPM_ALG_SHA1_SIZE or TPM_ALG_SHA256_SIZE
+ * @event_type: event type log. In skiboot, either EV_ACTION or EV_SEPARATOR.
+ * @event_msg: event log message that describes the event
+ *
+ * Returns O for success or a negative number if it fails.
+ */
+extern int tpm_extendl(TPM_Pcr pcr,
+		       TPM_Alg_Id alg1, uint8_t* digest1, size_t size1,
+		       TPM_Alg_Id alg2, uint8_t* digest2, size_t size2,
+		       uint32_t event_type, const char* event_msg);
+
 /* Add status property to the TPM devices */
 extern void tpm_add_status_property(void);
 
-- 
1.9.1



More information about the Skiboot mailing list