// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later /* Copyright 2020 IBM Corp. */ #include #include #include #include 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; }