diff options
-rw-r--r-- | libstb/status_codes.h | 4 | ||||
-rw-r--r-- | libstb/tpm_chip.c | 116 | ||||
-rw-r--r-- | libstb/tpm_chip.h | 26 |
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); |