aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstb/tss2/eventlog.c126
-rw-r--r--libstb/tss2/eventlog.h30
2 files changed, 156 insertions, 0 deletions
diff --git a/libstb/tss2/eventlog.c b/libstb/tss2/eventlog.c
new file mode 100644
index 0000000..f69db4b
--- /dev/null
+++ b/libstb/tss2/eventlog.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2020 IBM Corp. */
+
+#include <skiboot.h>
+
+#include <eventlog.h>
+#include <eventlib.h>
+#include <ibmtss/tssmarshal.h>
+
+
+int load_eventlog(TpmLogMgr *logmgr, uint8_t *eventlog_ptr,
+ uint32_t eventlog_size)
+{
+ TCG_PCR_EVENT2 *event2 = NULL;
+ TCG_PCR_EVENT *event = NULL;
+ uint8_t *log_ptr, *ptr;
+ uint32_t size;
+ int rc = 0;
+
+ event = zalloc(sizeof(TCG_PCR_EVENT));
+ if(!event){
+ rc = 1;
+ goto cleanup;
+ }
+
+ event2 = zalloc(sizeof(TCG_PCR_EVENT2));
+ if(!event2){
+ rc = 1;
+ goto cleanup;
+ }
+
+ logmgr->logMaxSize = eventlog_size;
+ logmgr->eventLogInMem = eventlog_ptr;
+ logmgr->logSize = 0;
+
+ log_ptr = logmgr->eventLogInMem;
+ size = sizeof(TCG_PCR_EVENT);
+
+ //first event in the log is a header
+ rc = TSS_EVENT_Line_LE_Unmarshal(event, &log_ptr, &size);
+ if(rc)
+ {
+ prlog(PR_INFO, "Couldn't read event log header event, rc=%d",
+ rc);
+ rc = 1;
+ goto cleanup;
+ }
+ //now iterate through all events
+ ptr = log_ptr;
+ do {
+ size = sizeof(TCG_PCR_EVENT2);
+ rc = TSS_EVENT2_Line_LE_Unmarshal(event2, &ptr, &size);
+ /* something went wrong in parsing (invalid values) or
+ * digest.count is 0 - which doesn't make sense - we stop.
+ */
+ if (rc || event2->digests.count == 0 )
+ break;
+ log_ptr = ptr;
+ } while(1);
+ logmgr->logSize = log_ptr - logmgr->eventLogInMem;
+ logmgr->newEventPtr = log_ptr;
+
+cleanup:
+ free(event);
+ free(event2);
+ return rc;
+}
+
+int add_to_eventlog(TpmLogMgr *logmgr, TCG_PCR_EVENT2 *event)
+{
+ uint32_t size = sizeof(TCG_PCR_EVENT2), rc = 0;
+ uint16_t written = 0, ev_size =0;
+
+ /* Calling Marshal function with a NULL buffer to obtain the event size.
+ * It's a well known and safe pattern used in TSS code.
+ * Then check if an event that larger will fit in evenlog buffer, and
+ * only after success here marshal it to eventlog buffer pointed by
+ * logmgr->newEventPtr.
+ */
+ TSS_EVENT2_Line_LE_Marshal(event, &ev_size, NULL, &size);
+ if(logmgr->logSize + ev_size > logmgr->logMaxSize){
+ return 1;
+ }
+ rc = TSS_EVENT2_Line_LE_Marshal(event, &written,
+ &(logmgr->newEventPtr), &size);
+ if(rc)
+ return rc;
+ logmgr->logSize += ev_size;
+
+ return rc;
+}
+
+int build_event(TCG_PCR_EVENT2 *event, TPMI_DH_PCR pcrHandle,
+ TPMI_ALG_HASH *hashes, uint8_t hashes_len,
+ const uint8_t **digests, uint32_t event_type,
+ const char* logmsg, uint32_t logmsg_len)
+{
+ uint16_t alg_digest_size;
+ uint32_t size;
+
+ memset(event, 0, sizeof(TCG_PCR_EVENT2));
+ event->pcrIndex = pcrHandle;
+ event->eventType = event_type;
+ event->digests.count = hashes_len;
+
+ size = sizeof(TPMI_ALG_HASH);
+ for (int i=0; i < event->digests.count; i++){
+ event->digests.digests[i].hashAlg = hashes[i];
+
+ TSS_TPMI_ALG_HASH_Marshalu(hashes+i, &alg_digest_size, NULL, &size);
+
+ if (alg_digest_size == 0)
+ return 1;
+ memcpy(&(event->digests.digests[i].digest), digests[i],
+ strlen(digests[i]) > alg_digest_size ?
+ strlen(digests[i]) : alg_digest_size);
+
+ }
+
+ event->eventSize = logmsg_len;
+ memset(&(event->event), 0, sizeof(event->event));
+ memcpy(&(event->event), logmsg,
+ event->eventSize > TCG_EVENT_LEN_MAX ?
+ TCG_EVENT_LEN_MAX - 1: event->eventSize);
+ return 0;
+}
diff --git a/libstb/tss2/eventlog.h b/libstb/tss2/eventlog.h
new file mode 100644
index 0000000..dd4a1d7
--- /dev/null
+++ b/libstb/tss2/eventlog.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2020 IBM Corp. */
+
+#ifndef __EVENTLOG_H
+#define __EVENTLOG_H
+
+#include <ibmtss/TPM_Types.h>
+#include <eventlib.h>
+
+#define MAX_TPM_LOG_MSG 128
+#define MAX_VENDOR_INFO_LEN 255
+
+struct _TpmLogMgr
+{
+ uint32_t logSize;
+ uint32_t logMaxSize;
+ uint8_t* newEventPtr;
+ uint8_t* eventLogInMem;
+};
+typedef struct _TpmLogMgr TpmLogMgr;
+
+
+int load_eventlog(TpmLogMgr *logmgr, uint8_t* eventlog_ptr,
+ uint32_t eventlog_size);
+int add_to_eventlog(TpmLogMgr *logmgr, TCG_PCR_EVENT2 *event);
+int build_event(TCG_PCR_EVENT2 *event, TPMI_DH_PCR pcrHandle,
+ TPMI_ALG_HASH *hashes, uint8_t hashes_len,
+ const uint8_t **digests, uint32_t event_type,
+ const char* logmsg, uint32_t logmsg_len);
+#endif //__EVENTLOG_H