diff options
author | Claudio Carvalho <cclaudio@linux.vnet.ibm.com> | 2016-09-28 05:01:23 -0300 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-10-10 15:29:35 +1100 |
commit | 282fff649acd0c1a7462c152506814f74341e057 (patch) | |
tree | 686d67a392c0403dd89e0493a0024ca7e9cc6236 /libstb | |
parent | 046a682f1e967a19227240f48d4036ee157ac7fb (diff) | |
download | talos-skiboot-282fff649acd0c1a7462c152506814f74341e057.tar.gz talos-skiboot-282fff649acd0c1a7462c152506814f74341e057.zip |
libstb/tss: add hostboot tpmLogMgr code for TPM 2.0
Hostboot exports the tpmLogMgr implementation for skiboot/PHYP. This
adds to skiboot the latest tpmLogMgr code, which supports multibank (it
is able to record events with multiple measurements into the firmware
event log).
tpmLogMgr code home and version:
https://github.com/open-power/hostboot/tree/master-p8/src/usr/secureboot/trusted
HEAD: 3ed4df70acbcf3927071ebd626d11e37f3656c38
Skiboot uses this tpmLogMgr API to:
- Initialize an existing event log. Hostboot allocates memory for the
firmware event log and announces it to skiboot/linux through the
linux,sml-base and linux,sml-size properties of the tpm device tree
node.
- Generate a new event to be added to the event log. The new event has a
digest list with the sha1 and sha256 measurements that are going to be
extended to the sha1 and sha256 PCR banks, respectively.
- Add a new event to the event log.
Signed-off-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libstb')
-rw-r--r-- | libstb/tss/tpmLogMgr.C | 573 | ||||
-rw-r--r-- | libstb/tss/tpmLogMgr.H | 244 |
2 files changed, 817 insertions, 0 deletions
diff --git a/libstb/tss/tpmLogMgr.C b/libstb/tss/tpmLogMgr.C new file mode 100644 index 00000000..89ab41a8 --- /dev/null +++ b/libstb/tss/tpmLogMgr.C @@ -0,0 +1,573 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file TpmLogMgr.C + * + * @brief TPM Event log manager + */ + +///////////////////////////////////////////////////////////////// +// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP // +///////////////////////////////////////////////////////////////// + +// ---------------------------------------------- +// Includes +// ---------------------------------------------- +#include <string.h> +#include "tpmLogMgr.H" +#ifdef __HOSTBOOT_MODULE +#include <sys/mm.h> +#include <util/align.H> +#include <secureboot/trustedboot_reasoncodes.H> +#else +#include "trustedboot_reasoncodes.H" +#endif +#include "trustedbootUtils.H" +#include "trustedboot.H" +#include "trustedTypes.H" + +#ifdef __cplusplus +namespace TRUSTEDBOOT +{ +#endif + + uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val) + { + return (sizeof(TCG_EfiSpecIdEventStruct) + val->vendorInfoSize); + } + +#ifdef __HOSTBOOT_MODULE + errlHndl_t TpmLogMgr_initialize(TpmLogMgr* val) + { + errlHndl_t err = TB_SUCCESS; + const char vendorInfo[] = "IBM"; + const char eventSignature[] = "Spec ID Event03"; + TCG_EfiSpecIdEventStruct* eventData = NULL; + + TCG_PCR_EVENT eventLogEntry; + + TRACUCOMP( g_trac_trustedboot, ">>initialize()"); + + if (NULL == val) + { + TRACFCOMP( g_trac_trustedboot, + "TPM LOG INIT FAIL"); + + /*@ + * @errortype + * @reasoncode RC_TPMLOGMGR_INIT_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPMLOGMGR_INITIALIZE + * @userdata1 0 + * @userdata2 0 + * @devdesc TPM log buffer init failure. + * @custdesc TPM log buffer init failure. + */ + err = tpmCreateErrorLog( MOD_TPMLOGMGR_INITIALIZE, + RC_TPMLOGMGR_INIT_FAIL, 0, 0); + + } + else + { + + memset(val, 0, sizeof(TpmLogMgr)); + val->logMaxSize = TPMLOG_BUFFER_SIZE; + + mutex_init( &val->logMutex ); + mutex_lock( &val->logMutex ); + + // Assign our new event pointer to the start + val->newEventPtr = val->eventLog; + memset(val->eventLog, 0, TPMLOG_BUFFER_SIZE); + + eventData = (TCG_EfiSpecIdEventStruct*) eventLogEntry.event; + + // Add the header event log + // Values here come from the PC ClientSpecificPlatformProfile spec + eventLogEntry.eventType = EV_NO_ACTION; + eventLogEntry.pcrIndex = 0; + eventLogEntry.eventSize = sizeof(TCG_EfiSpecIdEventStruct) + + sizeof(vendorInfo); + + memcpy(eventData->signature, eventSignature, + sizeof(eventSignature)); + eventData->platformClass = htole32(TPM_PLATFORM_SERVER); + eventData->specVersionMinor = TPM_SPEC_MINOR; + eventData->specVersionMajor = TPM_SPEC_MAJOR; + eventData->specErrata = TPM_SPEC_ERRATA; + eventData->uintnSize = 1; + eventData->numberOfAlgorithms = htole32(HASH_COUNT); + eventData->digestSizes[0].algorithmId = htole16(TPM_ALG_SHA256); + eventData->digestSizes[0].digestSize = htole16(TPM_ALG_SHA256_SIZE); + eventData->digestSizes[1].algorithmId = htole16(TPM_ALG_SHA1); + eventData->digestSizes[1].digestSize = htole16(TPM_ALG_SHA1_SIZE); + eventData->vendorInfoSize = sizeof(vendorInfo); + memcpy(eventData->vendorInfo, vendorInfo, sizeof(vendorInfo)); + val->newEventPtr = TCG_PCR_EVENT_logMarshal(&eventLogEntry, + val->newEventPtr); + + // Done, move our pointers + val->logSize += TCG_PCR_EVENT_marshalSize(&eventLogEntry); + + mutex_unlock( &val->logMutex ); + + // Debug display of raw data + TRACUBIN(g_trac_trustedboot, "tpmInitialize: Header Entry", + val->eventLog, val->logSize); + + TRACUCOMP( g_trac_trustedboot, + "<<initialize() LS:%d - %s", + val->logSize, + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + } + return err; + } +#endif + + errlHndl_t TpmLogMgr_initializeUsingExistingLog(TpmLogMgr* val, + uint8_t* eventLogPtr, + uint32_t eventLogSize) + { + errlHndl_t err = TB_SUCCESS; + TRACUCOMP( g_trac_trustedboot, + ">>initializeUsingExistingLog()"); + + do + { + + mutex_init( &val->logMutex ); + mutex_lock( &val->logMutex ); + + val->logMaxSize = eventLogSize; + val->eventLogInMem = eventLogPtr; + + // Ok, walk the log to figure out how big this is + val->logSize = TpmLogMgr_calcLogSize(val); + + if (0 == val->logSize) + { + TRACFCOMP( g_trac_trustedboot, + "TPM LOG INIT WALK FAIL"); + /*@ + * @errortype + * @reasoncode RC_TPMLOGMGR_LOGWALKFAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPMLOGMGR_INITIALIZEEXISTLOG + * @userdata1 0 + * @userdata2 0 + * @devdesc TPM log header entry is missing. + * @custdesc TPM log invalid format + */ + err = tpmCreateErrorLog(MOD_TPMLOGMGR_INITIALIZEEXISTLOG, + RC_TPMLOGMGR_LOGWALKFAIL, + 0, + 0); + break; + } + // We are good, let's move the newEventLogPtr + val->newEventPtr = val->eventLogInMem + val->logSize; + + } + while(0); + + if (TB_SUCCESS != err) + { + val->eventLogInMem = NULL; + val->newEventPtr = NULL; + val->logMaxSize = 0; + val->logSize = 0; + } + + mutex_unlock( &val->logMutex ); + + return err; + } + + errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val, + TCG_PCR_EVENT2* logEvent) + { + errlHndl_t err = TB_SUCCESS; + size_t newLogSize = TCG_PCR_EVENT2_marshalSize(logEvent); + + TRACUCOMP( g_trac_trustedboot, + ">>tpmAddEvent() PCR:%d Type:%d Size:%d", + logEvent->pcrIndex, logEvent->eventType, (int)newLogSize); + + mutex_lock( &val->logMutex ); + + do + { + + // Need to ensure we have room for the new event + // We have to leave room for the log full event as well + if (NULL == val->newEventPtr || + val->logSize + newLogSize > val->logMaxSize) + { + TRACFCOMP( g_trac_trustedboot, + "TPM LOG ADD FAIL PNULL(%d) LS(%d) New LS(%d)" + " Max LS(%d)", + (NULL == val->newEventPtr ? 0 : 1), + (int)val->logSize, (int)newLogSize, + (int)val->logMaxSize); + + /*@ + * @errortype + * @reasoncode RC_TPMLOGMGR_ADDEVENT_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPMLOGMGR_ADDEVENT + * @userdata1[0:31] Max log size + * @userdata1[32:63] Log buffer NULL + * @userdata2[0:31] Current Log Size + * @userdata2[32:63] New entry size + * @devdesc TPM log buffer add failure. + * @custdesc TPM log overflow + */ + err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, + RC_TPMLOGMGR_ADDEVENT_FAIL, + (uint64_t)val->logMaxSize << 32 | + (NULL == val->newEventPtr ? 0 : 1), + (uint64_t)val->logSize << 32 | + newLogSize); + + break; + } + + val->newEventPtr = TCG_PCR_EVENT2_logMarshal(logEvent, + val->newEventPtr); + + if (NULL == val->newEventPtr) + { + TRACFCOMP( g_trac_trustedboot, + "TPM LOG MARSHAL Fail"); + + /*@ + * @errortype + * @reasoncode RC_TPMLOGMGR_ADDEVENTMARSH_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPMLOGMGR_ADDEVENT + * @userdata1 0 + * @userdata2 0 + * @devdesc log buffer marshal failure. + * @custdesc TPM log operation failure + */ + err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, + RC_TPMLOGMGR_ADDEVENTMARSH_FAIL, + 0, + 0); + break; + } + + val->logSize += newLogSize; + + + } while ( 0 ); + + TRACUCOMP( g_trac_trustedboot, + "<<tpmAddEvent() LS:%d - %s", + (int)val->logSize, + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + + mutex_unlock( &val->logMutex ); + return err; + } + + uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val) + { + return val->logSize; + } + + void TpmLogMgr_dumpLog(TpmLogMgr* val) + { + + // Debug display of raw data + TRACUCOMP(g_trac_trustedboot, "tpmDumpLog Size : %d", + (int)val->logSize); + +#ifdef __HOSTBOOT_MODULE + // Debug display of raw data + if (NULL == val->eventLogInMem) + { + TRACUBIN(g_trac_trustedboot, "tpmDumpLog", + val->eventLog, val->logSize); + } + else + { +#endif + TRACUBIN(g_trac_trustedboot, "tpmDumpLog From Memory", + val->eventLogInMem, val->logSize); +#ifdef __HOSTBOOT_MODULE + } +#endif + } + + uint32_t TpmLogMgr_calcLogSize(TpmLogMgr* val) + { + uint32_t logSize = 0; + TCG_PCR_EVENT event; + TCG_PCR_EVENT2 event2; + bool errorFound = false; + const uint8_t* prevLogHandle = NULL; + const uint8_t* nextLogHandle = NULL; + + TRACUCOMP( g_trac_trustedboot, ">>calcLogSize"); + + // Start walking events + prevLogHandle = TpmLogMgr_getLogStartPtr(val); + do + { + + // First need to deal with the header entry + nextLogHandle = TCG_PCR_EVENT_logUnmarshal(&event, + prevLogHandle, + sizeof(TCG_PCR_EVENT), + &errorFound); + + if (NULL == nextLogHandle || errorFound || + EV_NO_ACTION != event.eventType || + 0 == event.eventSize) + { + TRACFCOMP( g_trac_trustedboot, "Header Marshal Failure"); + prevLogHandle = NULL; + break; + } + + if (( nextLogHandle - TpmLogMgr_getLogStartPtr(val)) > + val->logMaxSize) + { + TRACFCOMP( g_trac_trustedboot, "calcLogSize overflow"); + prevLogHandle = NULL; + break; + } + prevLogHandle = nextLogHandle; + + // Now iterate through all the other events + while (NULL != prevLogHandle) + { + nextLogHandle = TCG_PCR_EVENT2_logUnmarshal( + &event2, + prevLogHandle, + sizeof(TCG_PCR_EVENT2), + &errorFound); + if (NULL == nextLogHandle || errorFound) + { + // Failed parsing so we must have hit the end of log + break; + } + if (( nextLogHandle - TpmLogMgr_getLogStartPtr(val)) > + val->logMaxSize) + { + TRACFCOMP( g_trac_trustedboot, "calcLogSize overflow"); + prevLogHandle = NULL; + break; + } + prevLogHandle = nextLogHandle; + } + } + while (0); + + if (NULL == prevLogHandle) + { + logSize = 0; + } + else + { + logSize = (prevLogHandle - TpmLogMgr_getLogStartPtr(val)); + } + TRACUCOMP( g_trac_trustedboot, "<<calcLogSize : %d", logSize); + + return logSize; + } + + const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val) + { + TCG_PCR_EVENT event; + bool err = false; + const uint8_t* result = NULL; + + // Header event in the log is always first, we skip over that + const uint8_t* firstEvent = TpmLogMgr_getLogStartPtr(val); + memset(&event, 0, sizeof(TCG_PCR_EVENT)); + + firstEvent = TCG_PCR_EVENT_logUnmarshal(&event, firstEvent, + sizeof(TCG_PCR_EVENT), + &err); + if (NULL != firstEvent && !err && + firstEvent < val->newEventPtr) + { + result = firstEvent; + } + + return result; + } + + const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val, + const uint8_t* i_handle, + TCG_PCR_EVENT2* i_eventLog, + bool* o_err) + { + const uint8_t* l_resultPtr = NULL; + if (NULL == i_handle) + { + *o_err = true; + } + else + { + memset(i_eventLog, 0, sizeof(TCG_PCR_EVENT2)); + TRACUCOMP( g_trac_trustedboot, "TPM getNextEvent 0x%p", i_handle); + l_resultPtr = TCG_PCR_EVENT2_logUnmarshal(i_eventLog, i_handle, + sizeof(TCG_PCR_EVENT2), + o_err); + if (NULL == l_resultPtr) + { + // An error was detected, ensure o_err is set + *o_err = true; + } + else if (l_resultPtr >= val->newEventPtr) + { + l_resultPtr = NULL; + } + } + + return l_resultPtr; + } + + TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(TPM_Pcr i_pcr, + TPM_Alg_Id i_algId_1, + const uint8_t* i_digest_1, + size_t i_digestSize_1, + TPM_Alg_Id i_algId_2, + const uint8_t* i_digest_2, + size_t i_digestSize_2, + const char* i_logMsg) + { + TCG_PCR_EVENT2 eventLog; + size_t fullDigestSize_1 = 0; + size_t fullDigestSize_2 = 0; + + fullDigestSize_1 = getDigestSize(i_algId_1); + if (NULL != i_digest_2) + { + fullDigestSize_2 = getDigestSize(i_algId_2); + } + + memset(&eventLog, 0, sizeof(eventLog)); + eventLog.pcrIndex = i_pcr; + eventLog.eventType = EV_ACTION; + + // Update digest information + eventLog.digests.count = 1; + eventLog.digests.digests[0].algorithmId = i_algId_1; + memcpy(&(eventLog.digests.digests[0].digest), + i_digest_1, + (i_digestSize_1 < fullDigestSize_1 ? + i_digestSize_1 : fullDigestSize_1)); + + if (NULL != i_digest_2) + { + eventLog.digests.count = 2; + eventLog.digests.digests[1].algorithmId = i_algId_2; + memcpy(&(eventLog.digests.digests[1].digest), + i_digest_2, + (i_digestSize_2 < fullDigestSize_2 ? + i_digestSize_2 : fullDigestSize_2)); + } + // Event field data + eventLog.event.eventSize = strlen(i_logMsg); + memset(eventLog.event.event, 0, sizeof(eventLog.event.event)); + memcpy(eventLog.event.event, i_logMsg, + (strlen(i_logMsg) > MAX_TPM_LOG_MSG ? + MAX_TPM_LOG_MSG - 1 // Leave room for NULL termination + : strlen(i_logMsg)) ); + + return eventLog; + } + + + uint8_t* TpmLogMgr_getLogStartPtr(TpmLogMgr* val) + { +#ifdef __HOSTBOOT_MODULE + return (val->eventLogInMem == NULL ? + reinterpret_cast<uint8_t*>(&(val->eventLog)) : val->eventLogInMem); +#else + return val->eventLogInMem; +#endif + } + +#ifdef __HOSTBOOT_MODULE + errlHndl_t TpmLogMgr_getDevtreeInfo(TpmLogMgr* val, + uint64_t & io_logAddr, + size_t & o_allocationSize, + uint64_t & o_xscomAddr, + uint32_t & o_i2cMasterOffset) + { + errlHndl_t err = NULL; + + mutex_lock( &val->logMutex ); + + assert(io_logAddr != 0, "Invalid starting log address"); + assert(val->eventLogInMem == NULL, + "getDevtreeInfo can only be called once"); + + io_logAddr -= ALIGN_PAGE(TPMLOG_DEVTREE_SIZE); + // Align to 64KB for Opal + io_logAddr = ALIGN_DOWN_X(io_logAddr,64*KILOBYTE); + + val->inMemlogBaseAddr = io_logAddr; + o_allocationSize = TPMLOG_DEVTREE_SIZE; + o_xscomAddr = val->devtreeXscomAddr; + o_i2cMasterOffset = val->devtreeI2cMasterOffset; + + // Copy image. + val->eventLogInMem = (uint8_t*)(mm_block_map( + (void*)(io_logAddr), + ALIGN_PAGE(TPMLOG_DEVTREE_SIZE))); + // Copy log into new location + memset(val->eventLogInMem, 0, TPMLOG_DEVTREE_SIZE); + memcpy(val->eventLogInMem, val->eventLog, val->logSize); + val->newEventPtr = val->eventLogInMem + val->logSize; + + mutex_unlock( &val->logMutex ); + + TRACUCOMP( g_trac_trustedboot, + "<<getDevtreeInfo() Addr:%lX - %s", + io_logAddr, + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + return err; + } + + + void TpmLogMgr_setTpmDevtreeInfo(TpmLogMgr* val, + uint64_t i_xscomAddr, + uint32_t i_i2cMasterOffset) + { + val->devtreeXscomAddr = i_xscomAddr; + val->devtreeI2cMasterOffset = i_i2cMasterOffset; + } + +#endif + +#ifdef __cplusplus +} // end TRUSTEDBOOT +#endif diff --git a/libstb/tss/tpmLogMgr.H b/libstb/tss/tpmLogMgr.H new file mode 100644 index 00000000..5a44b9d4 --- /dev/null +++ b/libstb/tss/tpmLogMgr.H @@ -0,0 +1,244 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file tpmLogMgr.H + * + * @brief Trustedboot TPM Event Log Manager + * + */ + +///////////////////////////////////////////////////////////////// +// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP // +///////////////////////////////////////////////////////////////// + +#ifndef __TPMLOGMGR_H +#define __TPMLOGMGR_H +// ----------------------------------------------- +// Includes +// ----------------------------------------------- + +#ifdef __HOSTBOOT_MODULE +#include <sys/sync.h> +#endif +#include "trustedboot.H" +#include "trustedTypes.H" + +#ifdef __cplusplus +namespace TRUSTEDBOOT +{ +#endif + + /// Event log header algorithms + struct _TCG_EfiSpecIdEventAlgorithmSize + { + uint16_t algorithmId; + uint16_t digestSize; + } PACKED; + typedef struct _TCG_EfiSpecIdEventAlgorithmSize + TCG_EfiSpecIdEventAlgorithmSize; + + /// Event log header event data + struct _TCG_EfiSpecIdEventStruct + { + char signature[16]; + uint32_t platformClass; + uint8_t specVersionMinor; + uint8_t specVersionMajor; + uint8_t specErrata; + uint8_t uintnSize; + uint32_t numberOfAlgorithms; + TCG_EfiSpecIdEventAlgorithmSize digestSizes[HASH_COUNT]; + uint8_t vendorInfoSize; + char vendorInfo[0]; + } PACKED; + typedef struct _TCG_EfiSpecIdEventStruct TCG_EfiSpecIdEventStruct; + uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val); + + enum { + TPMLOG_BUFFER_SIZE = 3584, ///< Size of event log buffer for HB + TPMLOG_DEVTREE_SIZE = 64*1024, ///< Size to allocate for OPAL + }; + + struct _TpmLogMgr + { + uint32_t logSize; ///< Current byte size of log + uint32_t logMaxSize; ///< Space allocated for log entries + uint8_t* newEventPtr; ///< Pointer to location to add new event + uint8_t* eventLogInMem; ///< Event log allocated from memory +#ifdef __HOSTBOOT_MODULE + uint64_t inMemlogBaseAddr; ///< Base address of log for dev tree + uint64_t devtreeXscomAddr; ///< Devtree Xscom Address + uint32_t devtreeI2cMasterOffset; ///< Devtree I2c Master Offset + uint8_t eventLog[TPMLOG_BUFFER_SIZE]; ///< EventLog Buffer +#endif + mutex_t logMutex; ///< Log mutex + }; + typedef struct _TpmLogMgr TpmLogMgr; + +#ifdef __HOSTBOOT_MODULE + /** + * @brief Initialize the log manager + * @param[in/out] io_logMgr Return a pointer to the log manager + * @return errlHndl_t NULL if successful, otherwise a pointer to the + * error log. + */ + errlHndl_t TpmLogMgr_initialize(TpmLogMgr * io_logMgr); +#endif + + /** + * @brief Initialize the log manager to use a pre-existing buffer + * @param[in] val TpmLogMgr structure + * @param[in] eventLogPtr Pointer to event log to use + * @param[in] eventLogSize Allocated log buffer size + * @return errlHndl_t NULL if successful, otherwise a pointer to the + * error log. + */ + errlHndl_t TpmLogMgr_initializeUsingExistingLog(TpmLogMgr* val, + uint8_t* eventLogPtr, + uint32_t eventLogSize); + + /** + * @brief Add a new event to the log + * @param[in] val TpmLogMgr structure + * @param[in] logEvent Event log entry to add + * @return errlHndl_t NULL if successful, otherwise a pointer to the + * error log. + */ + errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val, TCG_PCR_EVENT2* logEvent); + + /** + * @brief Get current log size in bytes + * @param[in] val TpmLogMgr structure + * @return uint32_t Byte size of log + */ + uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val); + +#ifdef __HOSTBOOT_MODULE + /** + * @brief Retrieve devtree information + * @param[in] val TpmLogMgr structure + * @param[in/out] io_logAddr TPM Log address + * @param[out] o_allocationSize Total memory allocated for log + * @param[out] o_xscomAddr Chip Xscom Address + * @param[out] o_i2cMasterOffset I2c Master Offset + * @return errlHndl_t NULL if successful, otherwise a pointer to the + * error log. + * Function will allocate a new region in memory to store log + * for passing to opal + */ + errlHndl_t TpmLogMgr_getDevtreeInfo(TpmLogMgr* val, + uint64_t & io_logAddr, + size_t & o_allocationSize, + uint64_t & o_xscomAddr, + uint32_t & o_i2cMasterOffset); + + /** + * @brief Store TPM devtree node information + * @param[in] val TpmLogMgr structure + * @param[in] i_xscomAddr Chip Xscom Address + * @param[in] i_i2cMasterOffset i2c Master Offset + */ + void TpmLogMgr_setTpmDevtreeInfo(TpmLogMgr* val, + uint64_t i_xscomAddr, + uint32_t i_i2cMasterOffset); +#endif + + + /** + * @brief Calculate the log size in bytes by walking the log + * @param[in] val TpmLogMgr structure + * @return uint32_t Byte size of log + */ + uint32_t TpmLogMgr_calcLogSize(TpmLogMgr* val); + + /** + * @brief Get pointer to first event in eventLog past the header event + * @param[in] val TpmLogMgr structure + * @return uint8_t First event handle + * @retval NULL On empty log + * @retval !NULL First event handle + */ + const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val); + + /** + * @brief Get pointer to next event in log and unmarshal log contents + * into i_eventLog + * + * @param[in] i_handle Current event to unmarshal + * @param[in] i_eventLog EVENT2 structure to populate + * @param[in] o_err Indicates if an error occurred during + * LogUnmarshal. + * + * @return uint8_t* Pointer to the next event after i_handle + * @retval NULL When val contains last entry in log + * @retval !NULL When addition log entries available + */ + const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val, + const uint8_t* i_handle, + TCG_PCR_EVENT2* i_eventLog, + bool* o_err); + + /** + * @brief Get a TCG_PCR_EVENT2 populated with required data + * + * @param[in] i_pcr PCR to write to + * @param[in] i_algId_1 Algorithm to use + * @param[in] i_digest_1 Digest value to write to PCR + * @param[in] i_digestSize_1 Byte size of i_digest array + * @param[in] i_algId_2 Algorithm to use + * @param[in] i_digest_2 Digest value to write to PCR, NULL if not used + * @param[in] i_digestSize_2 Byte size of i_digest array + * @param[in] i_logMsg Null terminated Log message + * + * @return TCG_PCR_EVENT2 PCR event log + */ + TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(TPM_Pcr i_pcr, + TPM_Alg_Id i_algId_1, + const uint8_t* i_digest_1, + size_t i_digestSize_1, + TPM_Alg_Id i_algId_2, + const uint8_t* i_digest_2, + size_t i_digestSize_2, + const char* i_logMsg); + + /** + * @brief Dump contents of log to a trace + * @param[in] val TpmLogMgr structure + */ + void TpmLogMgr_dumpLog(TpmLogMgr* val); + + /** + * @brief Return a pointer to the start of the log + * @param[in] val TpmLogMgr structure + * @return uint8_t* Pointer to the start of the TPM log + */ + uint8_t* TpmLogMgr_getLogStartPtr(TpmLogMgr* val); + + +#ifdef __cplusplus +} // end TRUSTEDBOOT namespace +#endif + +#endif |