aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstb/status_codes.h4
-rw-r--r--libstb/tpm_chip.c116
-rw-r--r--libstb/tpm_chip.h26
3 files changed, 146 insertions, 0 deletions
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..1bfeb9a 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,83 @@ 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);