From 661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b Mon Sep 17 00:00:00 2001 From: Chris Engel Date: Fri, 3 Jun 2016 16:44:29 -0500 Subject: Trustedboot PCR Extend reworked to use task message queue Removed TPM log manager and required functions from HBB and replaced with a simple message queue Change-Id: I5f5a418b6ea8c0228229e8c45523385b488e2b6b RTC: 155519 ForwardPort: yes Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27133 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Christopher J. Engel Reviewed-by: Daniel M. Crowell --- src/usr/secureboot/base/makefile | 3 +- src/usr/secureboot/trusted/base/tpmLogMgr.C | 549 --------------------- src/usr/secureboot/trusted/base/tpmLogMgr.H | 241 --------- .../secureboot/trusted/base/trustedTypes_base.C | 504 ------------------- src/usr/secureboot/trusted/base/trustedbootMsg.C | 132 +++++ src/usr/secureboot/trusted/base/trustedbootMsg.H | 174 +++++++ src/usr/secureboot/trusted/base/trustedboot_base.C | 263 +++------- src/usr/secureboot/trusted/base/trustedboot_base.H | 67 --- src/usr/secureboot/trusted/makefile | 1 + src/usr/secureboot/trusted/test/tpmLogMgrTest.H | 2 +- src/usr/secureboot/trusted/test/trustedbootTest.H | 3 +- src/usr/secureboot/trusted/tpmLogMgr.C | 549 +++++++++++++++++++++ src/usr/secureboot/trusted/tpmLogMgr.H | 238 +++++++++ src/usr/secureboot/trusted/trustedTypes.C | 453 +++++++++++++++++ src/usr/secureboot/trusted/trustedboot.C | 285 ++++++++++- src/usr/secureboot/trusted/trustedboot.H | 47 +- src/usr/secureboot/trusted/trustedbootCmds.C | 6 +- src/usr/secureboot/trusted/trustedbootCmds.H | 2 +- src/usr/secureboot/trusted/trustedbootUtils.C | 17 +- 19 files changed, 1967 insertions(+), 1569 deletions(-) delete mode 100644 src/usr/secureboot/trusted/base/tpmLogMgr.C delete mode 100644 src/usr/secureboot/trusted/base/tpmLogMgr.H delete mode 100644 src/usr/secureboot/trusted/base/trustedTypes_base.C create mode 100644 src/usr/secureboot/trusted/base/trustedbootMsg.C create mode 100644 src/usr/secureboot/trusted/base/trustedbootMsg.H delete mode 100644 src/usr/secureboot/trusted/base/trustedboot_base.H create mode 100644 src/usr/secureboot/trusted/tpmLogMgr.C create mode 100644 src/usr/secureboot/trusted/tpmLogMgr.H (limited to 'src/usr/secureboot') diff --git a/src/usr/secureboot/base/makefile b/src/usr/secureboot/base/makefile index 63e7fa826..1c13cc289 100644 --- a/src/usr/secureboot/base/makefile +++ b/src/usr/secureboot/base/makefile @@ -32,8 +32,7 @@ OBJS += header.o OBJS += securerom.o OBJS += rom_entry.o OBJS += trustedboot_base.o -OBJS += $(if $(CONFIG_TPMDD),tpmLogMgr.o,) -OBJS += $(if $(CONFIG_TPMDD),trustedTypes_base.o,) +OBJS += $(if $(CONFIG_TPMDD),trustedbootMsg.o,) EXTRAINCDIR += ${ROOTPATH}/src/usr/secureboot/trusted/base VPATH += ${ROOTPATH}/src/usr/secureboot/trusted/base diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.C b/src/usr/secureboot/trusted/base/tpmLogMgr.C deleted file mode 100644 index d129bbaa1..000000000 --- a/src/usr/secureboot/trusted/base/tpmLogMgr.C +++ /dev/null @@ -1,549 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/secureboot/trusted/base/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 -#include "tpmLogMgr.H" -#ifdef __HOSTBOOT_MODULE -#include -#include -#include -#include "../trustedbootUtils.H" -#include "../trustedboot.H" -#else -#include "trustedboot_reasoncodes.H" -#include "trustedbootUtils.H" -#include "trustedboot.H" -#include "trustedTypes.H" -#endif - -#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. - */ - 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->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, - "<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 ); - TRACUCOMP( g_trac_trustedboot, - ">>initializeUsingExistingLog() 1"); - - val->logMaxSize = eventLogSize; - val->eventLogInMem = eventLogPtr; - - // Ok, walk the log to figure out how big this is - val->logSize = TpmLogMgr_calcLogSize(val); - TRACUCOMP( g_trac_trustedboot, - ">>initializeUsingExistingLog() 2"); - - 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. - */ - 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 Log buffer NULL - * @userdata2[0:31] Current Log Size - * @userdata2[32:63] New entry size - * @devdesc TPM log buffer add failure. - */ - err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, - RC_TPMLOGMGR_ADDEVENT_FAIL, - (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 malloc failure. - */ - err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, - RC_TPMLOGMGR_ADDEVENTMARSH_FAIL, - 0, - 0); - break; - } - - val->logSize += newLogSize; - - - } while ( 0 ); - - TRACUCOMP( g_trac_trustedboot, - "<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\n", - (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, "<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, - const uint8_t* i_digest, - size_t i_digestSize, - const char* i_logMsg) - { - TCG_PCR_EVENT2 eventLog; - - memset(&eventLog, 0, sizeof(eventLog)); - eventLog.pcrIndex = i_pcr; - eventLog.eventType = EV_ACTION; - - // Update digest information, we only use 1 entry - eventLog.digests.count = 1; - eventLog.digests.digests[0].algorithmId = i_algId; - memcpy(eventLog.digests.digests[0].digest.bytes, - i_digest, - (i_digestSize > sizeof(TPMU_HA) ? - sizeof(TPMU_HA) : i_digestSize)); - - // Event field data - eventLog.event.eventSize = strlen(i_logMsg); - memcpy(eventLog.event.event, i_logMsg, - (strlen(i_logMsg) > MAX_TPM_LOG_MSG ? - MAX_TPM_LOG_MSG : strlen(i_logMsg)) ); - - return eventLog; - } - - - uint8_t* TpmLogMgr_getLogStartPtr(TpmLogMgr* val) - { -#ifdef __HOSTBOOT_MODULE - return (val->eventLogInMem == NULL ? - reinterpret_cast(&(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, - "<devtreeXscomAddr = i_xscomAddr; - val->devtreeI2cMasterOffset = i_i2cMasterOffset; - } - -#endif - -#ifdef __cplusplus -} // end TRUSTEDBOOT -#endif diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.H b/src/usr/secureboot/trusted/base/tpmLogMgr.H deleted file mode 100644 index b12f5cb15..000000000 --- a/src/usr/secureboot/trusted/base/tpmLogMgr.H +++ /dev/null @@ -1,241 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/secureboot/trusted/base/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 -#include "../trustedboot.H" -#include "../trustedTypes.H" -#else -#include "trustedboot.H" -#include "trustedTypes.H" -#endif - -#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 = 1024, ///< Size of event log buffer in bytes - 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 Algorithm to use - * @param[in] i_digest Digest value to write to PCR - * @param[in] i_digestSize 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, - const uint8_t* i_digest, - size_t i_digestSize, - 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 diff --git a/src/usr/secureboot/trusted/base/trustedTypes_base.C b/src/usr/secureboot/trusted/base/trustedTypes_base.C deleted file mode 100644 index 9e4b35ff6..000000000 --- a/src/usr/secureboot/trusted/base/trustedTypes_base.C +++ /dev/null @@ -1,504 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/secureboot/trusted/base/trustedTypes_base.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 trustedTypes_base.C - * - * @brief Trusted boot type inline functions for hostboot base - */ - -///////////////////////////////////////////////////////////////// -// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP // -///////////////////////////////////////////////////////////////// - -// ---------------------------------------------- -// Includes -// ---------------------------------------------- -#include -#ifdef __HOSTBOOT_MODULE -#include "../trustedTypes.H" -#include "../trustedboot.H" -#else -#include "trustedTypes.H" -#include "trustedboot.H" -#endif - - -#ifdef __cplusplus -namespace TRUSTEDBOOT -{ -#endif - - uint32_t getDigestSize(TPM_Alg_Id i_algId) - { - uint32_t ret = 0; - switch (i_algId) - { - case TPM_ALG_SHA256: - ret = TPM_ALG_SHA256_SIZE; - break; - default: - ret = 0; - break; - }; - return ret; - } - - uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf) - { - uint16_t* field16 = (uint16_t*)i_logBuf; - *field16 = htole16(val->algorithmId); - i_logBuf += sizeof(uint16_t); - memcpy(i_logBuf, val->digest.bytes, - getDigestSize((TPM_Alg_Id)val->algorithmId)); - i_logBuf += getDigestSize((TPM_Alg_Id)val->algorithmId); - return i_logBuf; - } - - const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val, - const uint8_t* i_tpmBuf, bool* o_err) - { - size_t size = 0; - uint16_t* field16 = NULL; - - do { - *o_err = false; - - // algorithmId - size = sizeof(val->algorithmId); - field16 = (uint16_t*)i_tpmBuf; - val->algorithmId = le16toh(*field16); - // Ensure a valid count - if (val->algorithmId >= TPM_ALG_INVALID_ID) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal()" - " invalid algorithmId %d", - val->algorithmId); - break; - } - i_tpmBuf += size; - - // digest - size = getDigestSize((TPM_Alg_Id)val->algorithmId); - // Ensure a valid count - if (size >= TPM_ALG_INVALID_SIZE) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal() " - "invalid algorithm size of %d for algorithm id %d", - (int)size, val->algorithmId); - break; - } - - memcpy(&(val->digest.bytes), i_tpmBuf, size); - i_tpmBuf += size; - } while(0); - - return i_tpmBuf; - } - - size_t TPMT_HA_marshalSize(const TPMT_HA* val) - { - return (sizeof(val->algorithmId) + - getDigestSize((TPM_Alg_Id)(val->algorithmId))); - } - -#ifdef __cplusplus - bool TPMT_HA::operator==(const TPMT_HA& i_rhs) const - { - size_t digestSize = getDigestSize((TPM_Alg_Id)algorithmId); - return (algorithmId == i_rhs.algorithmId) && - (memcmp(digest.bytes, i_rhs.digest.bytes, digestSize) == 0); - } -#endif - - size_t TPML_DIGEST_VALUES_marshalSize(const TPML_DIGEST_VALUES* val) - { - size_t ret = sizeof(val->count); - for (size_t idx = 0; (idx < val->count && idx < HASH_COUNT); idx++) - { - ret += TPMT_HA_marshalSize(&(val->digests[idx])); - } - return ret; - } - - uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val, - uint8_t* i_logBuf) - { - uint32_t* field32 = (uint32_t*)i_logBuf; - if (HASH_COUNT < val->count) - { - i_logBuf = NULL; - } - else - { - *field32 = htole32(val->count); - i_logBuf += sizeof(uint32_t); - for (size_t idx = 0; idx < val->count; idx++) - { - i_logBuf = TPMT_HA_logMarshal(&(val->digests[idx]), i_logBuf); - if (NULL == i_logBuf) break; - } - } - return i_logBuf; - } - - const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val, - const uint8_t* i_tpmBuf, - bool* o_err) - { - size_t size = 0; - uint32_t* field32 = NULL; - do { - *o_err = false; - - // count - size = sizeof(val->count); - field32 = (uint32_t*)(i_tpmBuf); - val->count = le32toh(*field32); - // Ensure a valid count - if (val->count > HASH_COUNT) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot,"ERROR> " - "TPML_DIGEST_VALUES:logUnmarshal() " - "invalid digest count %d", - val->count); - break; - } - i_tpmBuf += size; - - // Iterate all digests - for (size_t idx = 0; idx < val->count; idx++) - { - i_tpmBuf = TPMT_HA_logUnmarshal(&(val->digests[idx]), - i_tpmBuf, o_err); - if (NULL == i_tpmBuf) - { - break; - } - } - } while(0); - - return i_tpmBuf; - } - -#ifdef __cplusplus - bool TPML_DIGEST_VALUES::operator==(const TPML_DIGEST_VALUES& i_rhs) const - { - bool result = (count == i_rhs.count); - // Iterate all digests - for (size_t idx = 0; idx < count; idx++) - { - result = (result && (digests[idx] == i_rhs.digests[idx])); - } - - return result; - } -#endif - - const uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val, - const uint8_t* i_tpmBuf, - size_t i_bufSize, - bool* o_err) - { - size_t size = 0; - uint32_t* field32; - - *o_err = false; - do { - // Ensure enough space for unmarshalled data - if (sizeof(TCG_PCR_EVENT) > i_bufSize) - { - *o_err = true; - i_tpmBuf = NULL; - break; - } - - // pcrIndex - size = sizeof(val->pcrIndex); - field32 = (uint32_t*)(i_tpmBuf); - val->pcrIndex = le32toh(*field32); - // Ensure a valid pcr index - if (val->pcrIndex >= IMPLEMENTATION_PCR) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot, - "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid pcrIndex %d", - val->pcrIndex); - break; - } - i_tpmBuf += size; - - // eventType - size = sizeof(val->eventType); - field32 = (uint32_t*)(i_tpmBuf); - val->eventType = le32toh(*field32); - // Ensure a valid event type - if (val->eventType == 0 || val->eventType >= EV_INVALID) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot, - "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventType %d", - val->eventType); - break; - } - i_tpmBuf += size; - - // digest - size = sizeof(val->digest); - memcpy(val->digest, i_tpmBuf, size); - i_tpmBuf += size; - - // eventSize - size = sizeof(val->eventSize); - field32 = (uint32_t*)(i_tpmBuf); - val->eventSize = le32toh(*field32); - // Ensure a valid eventSize - if (val->eventSize >= MAX_TPM_LOG_MSG) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot, - "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventSize %d", - val->eventSize); - break; - } - i_tpmBuf += size; - - memcpy(val->event, i_tpmBuf, val->eventSize); - i_tpmBuf += val->eventSize; - - } while(0); - - return i_tpmBuf; - } - - uint8_t* TCG_PCR_EVENT_logMarshal(const TCG_PCR_EVENT* val, - uint8_t* i_logBuf) - { - uint32_t* field32 = (uint32_t*)(i_logBuf); - *field32 = htole32(val->pcrIndex); - i_logBuf += sizeof(uint32_t); - - field32 = (uint32_t*)(i_logBuf); - *field32 = htole32(val->eventType); - i_logBuf += sizeof(uint32_t); - - memcpy(i_logBuf, val->digest, sizeof(val->digest)); - i_logBuf += sizeof(val->digest); - - field32 = (uint32_t*)(i_logBuf); - *field32 = htole32(val->eventSize); - i_logBuf += sizeof(uint32_t); - - if (val->eventSize > 0) - { - memcpy(i_logBuf, val->event, val->eventSize); - i_logBuf += val->eventSize; - } - return i_logBuf; - } - - size_t TCG_PCR_EVENT_marshalSize(const TCG_PCR_EVENT* val) - { - return (sizeof(TCG_PCR_EVENT) + val->eventSize - MAX_TPM_LOG_MSG); - } - - uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val, - uint8_t* i_logBuf) - { - uint32_t* field32 = (uint32_t*)i_logBuf; - if (MAX_TPM_LOG_MSG < val->eventSize) - { - i_logBuf = NULL; - } - else - { - *field32 = htole32(val->eventSize); - i_logBuf += sizeof(uint32_t); - - memcpy(i_logBuf, val->event, val->eventSize); - i_logBuf += val->eventSize; - } - return i_logBuf; - } - - const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val, - const uint8_t* i_tpmBuf, - bool* o_err) - { - size_t size = 0; - uint32_t* field32 = NULL; - do { - *o_err = false; - - // Event size - size = sizeof(val->eventSize); - field32 = (uint32_t*)(i_tpmBuf); - val->eventSize = le32toh(*field32); - i_tpmBuf += size; - - // Event - size = val->eventSize; - if (size > MAX_TPM_LOG_MSG) - { - *o_err = true; - i_tpmBuf = NULL; - break; - } - memcpy(&val->event, i_tpmBuf, size); - i_tpmBuf += size; - } while(0); - - return i_tpmBuf; - } - size_t TPM_EVENT_FIELD_marshalSize(const TPM_EVENT_FIELD* val) - { - return (sizeof(val->eventSize) + val->eventSize); - } - - -#ifdef __cplusplus - bool TPM_EVENT_FIELD::operator==(const TPM_EVENT_FIELD& i_rhs) const - { - return (eventSize == i_rhs.eventSize) && - (memcmp(event, i_rhs.event, eventSize) == 0); - } -#endif - - - size_t TCG_PCR_EVENT2_marshalSize(const TCG_PCR_EVENT2* val) - { - return (sizeof(val->pcrIndex) + sizeof(val->eventType) + - TPML_DIGEST_VALUES_marshalSize(&(val->digests)) + - TPM_EVENT_FIELD_marshalSize(&(val->event))); - } - - uint8_t* TCG_PCR_EVENT2_logMarshal(const TCG_PCR_EVENT2* val, - uint8_t* i_logBuf) - { - uint32_t* field32 = (uint32_t*)i_logBuf; - *field32 = htole32(val->pcrIndex); - i_logBuf += sizeof(uint32_t); - field32 = (uint32_t*)i_logBuf; - *field32 = htole32(val->eventType); - i_logBuf += sizeof(uint32_t); - - i_logBuf = TPML_DIGEST_VALUES_logMarshal(&(val->digests),i_logBuf); - if (NULL != i_logBuf) - { - i_logBuf = TPM_EVENT_FIELD_logMarshal(&(val->event),i_logBuf); - } - return i_logBuf; - } - - const uint8_t* TCG_PCR_EVENT2_logUnmarshal(TCG_PCR_EVENT2* val, - const uint8_t* i_tpmBuf, - size_t i_bufSize, - bool* o_err) - { - size_t size = 0; - uint32_t* field32 = NULL; - - do { - *o_err = false; - - // Ensure enough space for unmarshalled data - if (sizeof(TCG_PCR_EVENT2) > i_bufSize) - { - *o_err = true; - i_tpmBuf = NULL; - break; - } - - // pcrIndex - size = sizeof(val->pcrIndex); - field32 = (uint32_t*)(i_tpmBuf); - val->pcrIndex = le32toh(*field32); - // Ensure a valid pcr index - if (val->pcrIndex > IMPLEMENTATION_PCR) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:" - "logUnmarshal() invalid pcrIndex %d", - val->pcrIndex); - break; - } - i_tpmBuf += size; - - // eventType - size = sizeof(val->eventType); - field32 = (uint32_t*)(i_tpmBuf); - val->eventType = le32toh(*field32); - // Ensure a valid event type - if (val->eventType == 0 || - val->eventType >= EV_INVALID) - { - *o_err = true; - i_tpmBuf = NULL; - TRACFCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:" - "logUnmarshal() invalid eventType %d", - val->eventType); - break; - } - i_tpmBuf += size; - - // TPML_DIGEST_VALUES - i_tpmBuf = TPML_DIGEST_VALUES_logUnmarshal(&(val->digests), - i_tpmBuf, o_err); - if (i_tpmBuf == NULL) - { - break; - } - - // TPM EVENT FIELD - i_tpmBuf = TPM_EVENT_FIELD_logUnmarshal(&(val->event), - i_tpmBuf, o_err); - if (i_tpmBuf == NULL) - { - break; - } - } while(0); - - return i_tpmBuf; - } - -#ifdef __cplusplus - bool TCG_PCR_EVENT2::operator==(const TCG_PCR_EVENT2& i_rhs) const - { - return (pcrIndex == i_rhs.pcrIndex) && - (eventType == i_rhs.eventType) && - (digests == i_rhs.digests) && - (event == i_rhs.event); - } -} // end TRUSTEDBOOT -#endif diff --git a/src/usr/secureboot/trusted/base/trustedbootMsg.C b/src/usr/secureboot/trusted/base/trustedbootMsg.C new file mode 100644 index 000000000..9b5b2b847 --- /dev/null +++ b/src/usr/secureboot/trusted/base/trustedbootMsg.C @@ -0,0 +1,132 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/trusted/base/trustedbootMsg.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 trustedbootMsg.C + * @brief Trusted boot message implemenation + */ + +// ---------------------------------------------- +// Includes +// ---------------------------------------------- +#include +#include +#include +#include +#include "trustedbootMsg.H" +#include "../trustedboot.H" + +namespace TRUSTEDBOOT +{ + Message::Message(MessageType i_type, size_t i_len, + uint8_t* i_data, MessageMode i_mode): + iv_msg(msg_allocate()), + iv_errl(NULL), + iv_len(i_len), + iv_mode(i_mode), + iv_data(i_data) + { + iv_msg->type = i_type; + iv_msg->extra_data = static_cast(this); + } + + SyncMessage::SyncMessage(MessageType i_type, size_t i_len, + uint8_t* i_data): + Message(i_type, i_len, i_data, MSG_MODE_SYNC) + { + } + + void SyncMessage::response(msg_q_t i_msgQ) + { + errlHndl_t err = NULL; + // Send the response to the original caller of sendrecv() + int rc = msg_respond(i_msgQ, iv_msg); + if (rc) + { + TRACFCOMP( g_trac_trustedboot, + ERR_MRK "SyncMessage::response msg_respond failure %d", + rc); + /*@ + * @errortype ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_SYNCRESPONSE + * @reasoncode RC_MSGRESPOND_FAIL + * @userdata1 rc from msq_respond() + * @devdesc msg_respond() failed + * @custdesc Firmware error during system boot + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_SYNCRESPONSE, + RC_MSGRESPOND_FAIL, + rc, + 0, + true); + err->collectTrace(SECURE_COMP_NAME); + + // Log this failure here since we can't reply to caller + errlCommit(err, SECURE_COMP_ID); + + } + } + + AsyncMessage::AsyncMessage(MessageType i_type, size_t i_len, + uint8_t* i_data): + Message(i_type, i_len, i_data, MSG_MODE_ASYNC) + { + } + + void AsyncMessage::response(msg_q_t i_msgQ) + { + if (NULL != iv_errl) + { + TRACFCOMP(g_trac_trustedboot, + ERR_MRK "AsyncMessage::respond with error log"); + // Since we can't pass back to the caller we will commit the log + errlCommit(iv_errl, SECURE_COMP_ID); + + delete iv_errl; + iv_errl = NULL; + } + delete this; + } + + Message* Message::factory(MessageType i_type, size_t i_len, + uint8_t* i_data, MessageMode i_mode) + { + Message* msg = NULL; + switch (i_mode) + { + case MSG_MODE_SYNC: + msg = new SyncMessage(i_type, i_len, i_data); + break; + case MSG_MODE_ASYNC: + msg = new AsyncMessage(i_type, i_len, i_data); + break; + default: + assert(false, "trustedboot msg factory invalid mode"); + break; + } + return msg; + } + +}; diff --git a/src/usr/secureboot/trusted/base/trustedbootMsg.H b/src/usr/secureboot/trusted/base/trustedbootMsg.H new file mode 100644 index 000000000..4fb4edeaf --- /dev/null +++ b/src/usr/secureboot/trusted/base/trustedbootMsg.H @@ -0,0 +1,174 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/trusted/base/trustedbootMsg.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 trustedbootMsg.H + * + * @brief Trustedboot Message + * + */ +#ifndef __TRUSTEDBOOTMSG_H +#define __TRUSTEDBOOTMSG_H +// ----------------------------------------------- +// Includes +// ----------------------------------------------- +#include +#include +#include "../trustedTypes.H" + +namespace TRUSTEDBOOT +{ + + /// Message mode + enum MessageMode + { + MSG_MODE_SYNC, + MSG_MODE_ASYNC + }; + + /// Message Command type + enum MessageType + { + MSG_TYPE_NOOP, + MSG_TYPE_PCREXTEND, + MSG_TYPE_SHUTDOWN, + MSG_TYPE_LAST = MSG_TYPE_SHUTDOWN + }; + + /// PCREXTEND message data + struct PcrExtendMsgData + { + TPM_Pcr mPcrIndex; + TPM_Alg_Id mAlgId; + EventTypes mEventType; + size_t mDigestSize; + uint8_t mDigest[TPM_ALG_SHA256_SIZE]; + char mLogMsg[MAX_TPM_LOG_MSG]; + }; + + // Trustedboot message class + class Message + { + public: + /// @brief Static factory + /// @param[in] i_type Trustedboot TYPE + /// @param[in] i_len Byte length of i_data + /// @param[in] i_data The data as required by the specific command + /// @param[in] i_mode Message mode + static Message* factory(MessageType i_type = MSG_TYPE_NOOP, + size_t i_len = 0, + uint8_t* i_data = NULL, + MessageMode i_mode = MSG_MODE_SYNC); + + /// @brief Constructor + /// @param[in] i_type Message type + /// @param[in] i_len Byte length of i_data + /// @param[in] i_data The data as required by the specific command + /// @param[in] i_mode Message mode + Message(MessageType i_type = MSG_TYPE_NOOP, + size_t i_len = 0, + uint8_t* i_data = NULL, + MessageMode i_mode = MSG_MODE_SYNC); + + /// @brief Message dtor + virtual ~Message(void) + { + // Do NOT delete[] iv_data here. For synchronous messages + // the caller wants this data and expects to delete[] it + // itself. For async messages it is deleted in the dtor + + // Do NOT delete iv_errl here. For synchronous messages + // iv_errl is returned to the caller to commit and for + // asynchronous messages the error log is committed + // during the response processing + msg_free(iv_msg); + } + + /// @brief complete the processing when a response arrives + virtual void response(msg_q_t i_msgQ) = 0; + + msg_t* iv_msg; ///< Pointer back to our msg_q msg_t + errlHndl_t iv_errl; ///< Pointer to the errlHandl_t if needed + size_t iv_len; ///< Data Length + MessageMode iv_mode; ///< Message Mode + uint8_t* iv_data; ///< Pointer to the message data + + private: + // Disallow copying this class. Should suffice for disabling copy for + // all subclasses too. + Message& operator=(const Message&); + Message(const Message&); + + }; + + /// Trustedboot synchronous message + class SyncMessage : public Message + { + public: + /// @brief Constructor + /// @param[in] i_type Trustedboot TYPE + /// @param[in] i_len Byte length of i_data + /// @param[in] i_data The data as required by the specific command + SyncMessage(MessageType i_type = MSG_TYPE_NOOP, + size_t i_len = 0, + uint8_t* i_data = NULL); + + /// @brief Dtor + virtual ~SyncMessage(void) + { + delete[] iv_data; + iv_data = NULL; + } + + /// @brief complete the processing when a response arrives + virtual void response(msg_q_t i_msgQ); + + }; + + /// Trustedboot asynchronous message + class AsyncMessage : public Message + { + public: + /// @brief Constructor + /// @param[in] i_type Trustedboot TYPE + /// @param[in] i_len Byte length of i_data + /// @param[in] i_data The data as required by the specific command + AsyncMessage(MessageType i_type = MSG_TYPE_NOOP, + size_t i_len = 0, + uint8_t* i_data = NULL); + + /// @brief Dtor + virtual ~AsyncMessage(void) + { + delete[] iv_data; + iv_data = NULL; + } + + /// @brief complete the processing when a response arrives + virtual void response(msg_q_t i_msgQ); + }; + +}; + +#endif diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C index 61e7a12a2..3f9fc9576 100644 --- a/src/usr/secureboot/trusted/base/trustedboot_base.C +++ b/src/usr/secureboot/trusted/base/trustedboot_base.C @@ -34,6 +34,7 @@ // ---------------------------------------------- #include #include +#include #include #include #include @@ -41,11 +42,10 @@ #include #include #include -#include "trustedboot_base.H" #include "../trustedboot.H" #include "../trustedbootCmds.H" #include "../trustedbootUtils.H" -#include "tpmLogMgr.H" +#include "trustedbootMsg.H" // ---------------------------------------------- // Trace definitions @@ -62,10 +62,6 @@ namespace TRUSTEDBOOT /// Global object to store TPM status SystemTpms systemTpms; -SystemTpms::SystemTpms() -{ -} - TpmTarget::TpmTarget() { memset(this, 0, sizeof(TpmTarget)); @@ -77,216 +73,113 @@ TpmTarget::TpmTarget() errlHndl_t pcrExtend(TPM_Pcr i_pcr, - uint8_t* i_digest, + const uint8_t* i_digest, size_t i_digestSize, - const char* i_logMsg) + const char* i_logMsg, + bool i_sendAsync) { errlHndl_t err = NULL; #ifdef CONFIG_TPMDD - TPM_Alg_Id algId = TPM_ALG_SHA256; + MessageMode mode = MSG_MODE_ASYNC; - size_t fullDigestSize = getDigestSize(algId); - char logMsg[MAX_TPM_LOG_MSG]; + assert(!systemTpms.tpmDaemonShutdown, "TPM Daemon shutdown"); TRACDCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend()" ); TRACUCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend() pcr=%d msg='%s'", i_pcr, i_logMsg); - TRACFBIN(g_trac_trustedboot, "pcrExtend() digest:", i_digest, i_digestSize); + TRACUBIN(g_trac_trustedboot, "pcrExtend() digest:", i_digest, i_digestSize); - // Ensure proper digest size - uint8_t digestData[fullDigestSize]; - memset(digestData, 0, sizeof(digestData)); + // msgData will be freed when message is processed for async + // or below for sync message + PcrExtendMsgData* msgData = new PcrExtendMsgData; + memset(msgData, 0, sizeof(PcrExtendMsgData)); + msgData->mPcrIndex = i_pcr; + msgData->mAlgId = TPM_ALG_SHA256; + msgData->mEventType = EV_ACTION; + msgData->mDigestSize = (i_digestSize < sizeof(msgData->mDigest) ? + i_digestSize : sizeof(msgData->mDigest)); - // copy over the incoming digest to append or truncate to what we need - memcpy(digestData, i_digest, - (i_digestSize < fullDigestSize ? i_digestSize : fullDigestSize)); - // Truncate logMsg if required - memset(logMsg, 0, sizeof(logMsg)); - memcpy(logMsg, i_logMsg, - (strlen(i_logMsg) < MAX_TPM_LOG_MSG ? strlen(i_logMsg) : - MAX_TPM_LOG_MSG)); + // copy over the incoming digest and truncate to what we need + memcpy(msgData->mDigest, i_digest, msgData->mDigestSize); + // Truncate logMsg if required + memcpy(msgData->mLogMsg, i_logMsg, + (strlen(i_logMsg) < sizeof(msgData->mLogMsg) ? strlen(i_logMsg) : + sizeof(msgData->mLogMsg)-1) // Leave room for NULL termination + ); - for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx++) + if (!i_sendAsync) { - // Add the event to this TPM, if an error occurs the TPM will - // be marked as failed and the error log committed - pcrExtendSingleTpm(systemTpms.tpm[idx], - i_pcr, - algId, - digestData, - fullDigestSize, - logMsg); + mode = MSG_MODE_SYNC; } - // Lastly make sure we are in a state where we have a functional TPM - err = tpmVerifyFunctionalTpmExists(); - - - TRACUCOMP( g_trac_trustedboot, - EXIT_MRK"pcrExtend() - %s", - ((NULL == err) ? "No Error" : "With Error") ); - -#endif - return err; -} - -#ifdef CONFIG_TPMDD -void pcrExtendSingleTpm(TpmTarget & io_target, - TPM_Pcr i_pcr, - TPM_Alg_Id i_algId, - uint8_t* i_digest, - size_t i_digestSize, - const char* i_logMsg) -{ - errlHndl_t err = NULL; - TCG_PCR_EVENT2 eventLog; - bool unlock = false; + Message* msg = Message::factory(MSG_TYPE_PCREXTEND, + sizeof(PcrExtendMsgData), + reinterpret_cast(msgData), + mode); + // Message owns msgData now + msgData = NULL; - do + if (!i_sendAsync) { - mutex_lock( &io_target.tpmMutex ); - unlock = true; - - // Allocate the TPM log if it hasn't been already - if (!io_target.failed && - io_target.available && - NULL == io_target.logMgr) - { - io_target.logMgr = new TpmLogMgr; - err = TpmLogMgr_initialize(io_target.logMgr); - if (NULL != err) - { - break; - } - } - - // Log the event, we will do this in two scenarios - // - !initAttempted - prior to IPL of the TPM we log for replay - // - initAttempted && !failed - TPM is functional so we log - if ((io_target.available && - !io_target.initAttempted) || - (io_target.available && - io_target.initAttempted && - !io_target.failed)) + int rc = msg_sendrecv(systemTpms.msgQ, msg->iv_msg); + if (0 == rc) { - // Fill in TCG_PCR_EVENT2 and add to log - eventLog = TpmLogMgr_genLogEventPcrExtend(i_pcr, i_algId, i_digest, - i_digestSize, i_logMsg); - err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog); - if (NULL != err) - { - break; - } + err = msg->iv_errl; + msg->iv_errl = NULL; } - - // If the TPM init has occurred and it is currently - // functional we will do our extension - if (io_target.available && - io_target.initAttempted && - !io_target.failed) + // Sendrecv failure + else { - - err = tpmCmdPcrExtend(&io_target, - i_pcr, - i_algId, - i_digest, - i_digestSize); - if (NULL != err) - { - break; - } + /*@ + * @errortype ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_PCREXTEND + * @reasoncode RC_PCREXTEND_SENDRECV_FAIL + * @userdata1 rc from msq_sendrecv() + * @devdesc msg_sendrecv() failed + * @custdesc Firmware error during system boot + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_PCREXTEND, + RC_PCREXTEND_SENDRECV_FAIL, + rc, + 0, + true); + err->collectTrace(SECURE_COMP_NAME); } - } while ( 0 ); - - if (NULL != err) - { - // We failed to extend to this TPM we can no longer use it - tpmMarkFailed(&io_target); - - // Log this failure - errlCommit(err, SECURE_COMP_ID); - err = NULL; + delete msg; + msg = NULL; } - - if (unlock) + else { - mutex_unlock(&io_target.tpmMutex); - } - return; -} - -void tpmMarkFailed(TpmTarget * io_target) -{ - - TRACFCOMP( g_trac_trustedboot, - ENTER_MRK"tpmMarkFailed() Marking TPM as failed : " - "tgt=0x%X chip=%d", - TARGETING::get_huid(io_target->nodeTarget), - io_target->chip); - - io_target->failed = true; - /// @todo RTC:125287 Add fail marker to TPM log and disable TPM access - -} - -errlHndl_t tpmVerifyFunctionalTpmExists() -{ - errlHndl_t err = NULL; - bool foundFunctional = false; - - for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++) - { - if (!systemTpms.tpm[idx].failed || - !systemTpms.tpm[idx].initAttempted) + int rc = msg_send(systemTpms.msgQ, msg->iv_msg); + if (rc) { - foundFunctional = true; - break; + /*@ + * @errortype ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_PCREXTEND + * @reasoncode RC_PCREXTEND_SEND_FAIL + * @userdata1 rc from msq_send() + * @devdesc msg_send() failed + * @custdesc Firmware error during system boot + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_PCREXTEND, + RC_PCREXTEND_SEND_FAIL, + rc, + 0, + true); + err->collectTrace(SECURE_COMP_NAME); } } - if (!foundFunctional) - { - TRACFCOMP( g_trac_trustedboot, - "NO FUNCTIONAL TPM FOUND"); - - /*@ - * @errortype - * @reasoncode RC_TPM_NOFUNCTIONALTPM_FAIL - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid MOD_TPM_VERIFYFUNCTIONAL - * @userdata1 0 - * @userdata2 0 - * @devdesc No functional TPMs exist in the system - */ - err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - MOD_TPM_VERIFYFUNCTIONAL, - RC_TPM_NOFUNCTIONALTPM_FAIL, - 0, 0, - true /*Add HB SW Callout*/ ); - - err->collectTrace( SECURE_COMP_NAME ); - } - - return err; -} + TRACUCOMP( g_trac_trustedboot, + EXIT_MRK"pcrExtend() - %s", + ((NULL == err) ? "No Error" : "With Error") ); -errlHndl_t tpmCreateErrorLog(const uint8_t i_modId, - const uint16_t i_reasonCode, - const uint64_t i_user1, - const uint64_t i_user2) -{ - errlHndl_t err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - i_modId, - i_reasonCode, - i_user1, - i_user2, - true /*Add HB SW Callout*/ ); - err->collectTrace( SECURE_COMP_NAME ); +#endif return err; } -#endif - } // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.H b/src/usr/secureboot/trusted/base/trustedboot_base.H deleted file mode 100644 index 70d160b02..000000000 --- a/src/usr/secureboot/trusted/base/trustedboot_base.H +++ /dev/null @@ -1,67 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/secureboot/trusted/base/trustedboot_base.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 trustedboot_base.H - * - * @brief Trustedboot TPM interfaces in HB base - * - */ -#ifndef __TRUSTEDBOOT_BASE_H -#define __TRUSTEDBOOT_BASE_H -// ----------------------------------------------- -// Includes -// ----------------------------------------------- -#include -#include "../trustedTypes.H" - -namespace TRUSTEDBOOT -{ - - -/** - * @brief Verify a functional TPM still exists in the system - * @return errlHndl_t NULL if TPM available, otherwise a pointer to the - * error log. -*/ -errlHndl_t tpmVerifyFunctionalTpmExists(); - -/** - * @brief Extend a measurement into a TPM and log - * @param[in/out] io_target Current TPM target structure - * @param[in] i_pcr PCR to write to - * @param[in] i_digest Digest value to write to PCR - * @param[in] i_digestSize Byte size of i_digest data - * @param[in] i_logMsg Null terminated log message - */ -void pcrExtendSingleTpm(TpmTarget & io_target, - TPM_Pcr i_pcr, - TPM_Alg_Id i_algId, - uint8_t* i_digest, - size_t i_digestSize, - const char* i_logMsg); - - -} // end TRUSTEDBOOT namespace -#endif diff --git a/src/usr/secureboot/trusted/makefile b/src/usr/secureboot/trusted/makefile index 6fd41f709..b3da5a509 100644 --- a/src/usr/secureboot/trusted/makefile +++ b/src/usr/secureboot/trusted/makefile @@ -28,6 +28,7 @@ MODULE = secureboot_trusted OBJS += $(if $(CONFIG_TPMDD),trustedboot.o,) OBJS += $(if $(CONFIG_TPMDD),trustedbootCmds.o,) OBJS += $(if $(CONFIG_TPMDD),trustedTypes.o,) +OBJS += $(if $(CONFIG_TPMDD),tpmLogMgr.o,) OBJS += $(if $(CONFIG_TPMDD),trustedbootUtils.o,) SUBDIRS += $(if $(CONFIG_TPMDD),test.d,) diff --git a/src/usr/secureboot/trusted/test/tpmLogMgrTest.H b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H index cf61de420..f2f1d4d54 100755 --- a/src/usr/secureboot/trusted/test/tpmLogMgrTest.H +++ b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H @@ -36,7 +36,7 @@ #include #include #include "../trustedTypes.H" -#include "../base/tpmLogMgr.H" +#include "../tpmLogMgr.H" using namespace TRUSTEDBOOT; diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H index 12f7a9de0..e19ad1d00 100755 --- a/src/usr/secureboot/trusted/test/trustedbootTest.H +++ b/src/usr/secureboot/trusted/test/trustedbootTest.H @@ -41,8 +41,7 @@ #include "../trustedTypes.H" #include "../trustedboot.H" #include "../trustedbootCmds.H" -#include "../base/trustedboot_base.H" -#include "../base/tpmLogMgr.H" +#include "../tpmLogMgr.H" using namespace TRUSTEDBOOT; diff --git a/src/usr/secureboot/trusted/tpmLogMgr.C b/src/usr/secureboot/trusted/tpmLogMgr.C new file mode 100644 index 000000000..f5ab74a64 --- /dev/null +++ b/src/usr/secureboot/trusted/tpmLogMgr.C @@ -0,0 +1,549 @@ +/* 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 +#include "tpmLogMgr.H" +#ifdef __HOSTBOOT_MODULE +#include +#include +#include +#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. + */ + 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->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, + "<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 ); + TRACUCOMP( g_trac_trustedboot, + ">>initializeUsingExistingLog() 1"); + + val->logMaxSize = eventLogSize; + val->eventLogInMem = eventLogPtr; + + // Ok, walk the log to figure out how big this is + val->logSize = TpmLogMgr_calcLogSize(val); + TRACUCOMP( g_trac_trustedboot, + ">>initializeUsingExistingLog() 2"); + + 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. + */ + 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 Log buffer NULL + * @userdata2[0:31] Current Log Size + * @userdata2[32:63] New entry size + * @devdesc TPM log buffer add failure. + */ + err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, + RC_TPMLOGMGR_ADDEVENT_FAIL, + (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 malloc failure. + */ + err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT, + RC_TPMLOGMGR_ADDEVENTMARSH_FAIL, + 0, + 0); + break; + } + + val->logSize += newLogSize; + + + } while ( 0 ); + + TRACUCOMP( g_trac_trustedboot, + "<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\n", + (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, "<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, + const uint8_t* i_digest, + size_t i_digestSize, + const char* i_logMsg) + { + TCG_PCR_EVENT2 eventLog; + + memset(&eventLog, 0, sizeof(eventLog)); + eventLog.pcrIndex = i_pcr; + eventLog.eventType = EV_ACTION; + + // Update digest information, we only use 1 entry + eventLog.digests.count = 1; + eventLog.digests.digests[0].algorithmId = i_algId; + memcpy(eventLog.digests.digests[0].digest.bytes, + i_digest, + (i_digestSize > sizeof(TPMU_HA) ? + sizeof(TPMU_HA) : i_digestSize)); + + // 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(&(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, + "<devtreeXscomAddr = i_xscomAddr; + val->devtreeI2cMasterOffset = i_i2cMasterOffset; + } + +#endif + +#ifdef __cplusplus +} // end TRUSTEDBOOT +#endif diff --git a/src/usr/secureboot/trusted/tpmLogMgr.H b/src/usr/secureboot/trusted/tpmLogMgr.H new file mode 100644 index 000000000..15dd6e653 --- /dev/null +++ b/src/usr/secureboot/trusted/tpmLogMgr.H @@ -0,0 +1,238 @@ +/* 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 +#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 = 1024, ///< Size of event log buffer in bytes + 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 Algorithm to use + * @param[in] i_digest Digest value to write to PCR + * @param[in] i_digestSize 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, + const uint8_t* i_digest, + size_t i_digestSize, + 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 diff --git a/src/usr/secureboot/trusted/trustedTypes.C b/src/usr/secureboot/trusted/trustedTypes.C index 48b069a3b..709236939 100644 --- a/src/usr/secureboot/trusted/trustedTypes.C +++ b/src/usr/secureboot/trusted/trustedTypes.C @@ -92,6 +92,24 @@ namespace TRUSTEDBOOT return o_tpmBuf; } + uint32_t getDigestSize(const TPM_Alg_Id i_algId) + { + uint32_t ret = 0; + switch (i_algId) + { + case TPM_ALG_SHA1: + ret = TPM_ALG_SHA1_SIZE; + break; + case TPM_ALG_SHA256: + ret = TPM_ALG_SHA256_SIZE; + break; + default: + ret = 0; + break; + }; + return ret; + } + const uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal( TPML_TAGGED_TPM_PROPERTY* val, const uint8_t* i_tpmBuf, @@ -469,6 +487,441 @@ namespace TRUSTEDBOOT val, sizeof(TPMS_AUTH_COMMAND)); } + + uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf) + { + uint16_t* field16 = (uint16_t*)i_logBuf; + *field16 = htole16(val->algorithmId); + i_logBuf += sizeof(uint16_t); + memcpy(i_logBuf, val->digest.bytes, + getDigestSize((TPM_Alg_Id)val->algorithmId)); + i_logBuf += getDigestSize((TPM_Alg_Id)val->algorithmId); + return i_logBuf; + } + + const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val, + const uint8_t* i_tpmBuf, bool* o_err) + { + size_t size = 0; + uint16_t* field16 = NULL; + + do { + *o_err = false; + + // algorithmId + size = sizeof(val->algorithmId); + field16 = (uint16_t*)i_tpmBuf; + val->algorithmId = le16toh(*field16); + // Ensure a valid count + if (val->algorithmId >= TPM_ALG_INVALID_ID) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal()" + " invalid algorithmId %d", + val->algorithmId); + break; + } + i_tpmBuf += size; + + // digest + size = getDigestSize((TPM_Alg_Id)val->algorithmId); + // Ensure a valid count + if (size >= TPM_ALG_INVALID_SIZE) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot,"ERROR> TPMT_HA:logUnmarshal() " + "invalid algorithm size of %d for algorithm id %d", + (int)size, val->algorithmId); + break; + } + + memcpy(&(val->digest.bytes), i_tpmBuf, size); + i_tpmBuf += size; + } while(0); + + return i_tpmBuf; + } + + size_t TPMT_HA_marshalSize(const TPMT_HA* val) + { + return (sizeof(val->algorithmId) + + getDigestSize((TPM_Alg_Id)(val->algorithmId))); + } + #ifdef __cplusplus + bool TPMT_HA::operator==(const TPMT_HA& i_rhs) const + { + size_t digestSize = getDigestSize((TPM_Alg_Id)algorithmId); + return (algorithmId == i_rhs.algorithmId) && + (memcmp(digest.bytes, i_rhs.digest.bytes, digestSize) == 0); + } +#endif + + size_t TPML_DIGEST_VALUES_marshalSize(const TPML_DIGEST_VALUES* val) + { + size_t ret = sizeof(val->count); + for (size_t idx = 0; (idx < val->count && idx < HASH_COUNT); idx++) + { + ret += TPMT_HA_marshalSize(&(val->digests[idx])); + } + return ret; + } + + uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val, + uint8_t* i_logBuf) + { + uint32_t* field32 = (uint32_t*)i_logBuf; + if (HASH_COUNT < val->count) + { + i_logBuf = NULL; + } + else + { + *field32 = htole32(val->count); + i_logBuf += sizeof(uint32_t); + for (size_t idx = 0; idx < val->count; idx++) + { + i_logBuf = TPMT_HA_logMarshal(&(val->digests[idx]), i_logBuf); + if (NULL == i_logBuf) break; + } + } + return i_logBuf; + } + + const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val, + const uint8_t* i_tpmBuf, + bool* o_err) + { + size_t size = 0; + uint32_t* field32 = NULL; + do { + *o_err = false; + + // count + size = sizeof(val->count); + field32 = (uint32_t*)(i_tpmBuf); + val->count = le32toh(*field32); + // Ensure a valid count + if (val->count > HASH_COUNT) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot,"ERROR> " + "TPML_DIGEST_VALUES:logUnmarshal() " + "invalid digest count %d", + val->count); + break; + } + i_tpmBuf += size; + + // Iterate all digests + for (size_t idx = 0; idx < val->count; idx++) + { + i_tpmBuf = TPMT_HA_logUnmarshal(&(val->digests[idx]), + i_tpmBuf, o_err); + if (NULL == i_tpmBuf) + { + break; + } + } + } while(0); + + return i_tpmBuf; + } + +#ifdef __cplusplus + bool TPML_DIGEST_VALUES::operator==(const TPML_DIGEST_VALUES& i_rhs) const + { + bool result = (count == i_rhs.count); + // Iterate all digests + for (size_t idx = 0; idx < count; idx++) + { + result = (result && (digests[idx] == i_rhs.digests[idx])); + } + + return result; + } +#endif + + const uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val, + const uint8_t* i_tpmBuf, + size_t i_bufSize, + bool* o_err) + { + size_t size = 0; + uint32_t* field32; + + *o_err = false; + do { + // Ensure enough space for unmarshalled data + if (sizeof(TCG_PCR_EVENT) > i_bufSize) + { + *o_err = true; + i_tpmBuf = NULL; + break; + } + + // pcrIndex + size = sizeof(val->pcrIndex); + field32 = (uint32_t*)(i_tpmBuf); + val->pcrIndex = le32toh(*field32); + // Ensure a valid pcr index + if (val->pcrIndex >= IMPLEMENTATION_PCR) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot, + "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid pcrIndex %d", + val->pcrIndex); + break; + } + i_tpmBuf += size; + + // eventType + size = sizeof(val->eventType); + field32 = (uint32_t*)(i_tpmBuf); + val->eventType = le32toh(*field32); + // Ensure a valid event type + if (val->eventType == 0 || val->eventType >= EV_INVALID) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot, + "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventType %d", + val->eventType); + break; + } + i_tpmBuf += size; + + // digest + size = sizeof(val->digest); + memcpy(val->digest, i_tpmBuf, size); + i_tpmBuf += size; + + // eventSize + size = sizeof(val->eventSize); + field32 = (uint32_t*)(i_tpmBuf); + val->eventSize = le32toh(*field32); + // Ensure a valid eventSize + if (val->eventSize >= MAX_TPM_LOG_MSG) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot, + "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventSize %d", + val->eventSize); + break; + } + i_tpmBuf += size; + + memcpy(val->event, i_tpmBuf, val->eventSize); + i_tpmBuf += val->eventSize; + + } while(0); + + return i_tpmBuf; + } + + uint8_t* TCG_PCR_EVENT_logMarshal(const TCG_PCR_EVENT* val, + uint8_t* i_logBuf) + { + uint32_t* field32 = (uint32_t*)(i_logBuf); + *field32 = htole32(val->pcrIndex); + i_logBuf += sizeof(uint32_t); + + field32 = (uint32_t*)(i_logBuf); + *field32 = htole32(val->eventType); + i_logBuf += sizeof(uint32_t); + + memcpy(i_logBuf, val->digest, sizeof(val->digest)); + i_logBuf += sizeof(val->digest); + + field32 = (uint32_t*)(i_logBuf); + *field32 = htole32(val->eventSize); + i_logBuf += sizeof(uint32_t); + + if (val->eventSize > 0) + { + memcpy(i_logBuf, val->event, val->eventSize); + i_logBuf += val->eventSize; + } + return i_logBuf; + } + + size_t TCG_PCR_EVENT_marshalSize(const TCG_PCR_EVENT* val) + { + return (sizeof(TCG_PCR_EVENT) + val->eventSize - MAX_TPM_LOG_MSG); + } + + uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val, + uint8_t* i_logBuf) + { + uint32_t* field32 = (uint32_t*)i_logBuf; + if (MAX_TPM_LOG_MSG < val->eventSize) + { + i_logBuf = NULL; + } + else + { + *field32 = htole32(val->eventSize); + i_logBuf += sizeof(uint32_t); + + memcpy(i_logBuf, val->event, val->eventSize); + i_logBuf += val->eventSize; + } + return i_logBuf; + } + + const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val, + const uint8_t* i_tpmBuf, + bool* o_err) + { + size_t size = 0; + uint32_t* field32 = NULL; + do { + *o_err = false; + + // Event size + size = sizeof(val->eventSize); + field32 = (uint32_t*)(i_tpmBuf); + val->eventSize = le32toh(*field32); + i_tpmBuf += size; + + // Event + size = val->eventSize; + if (size > MAX_TPM_LOG_MSG) + { + *o_err = true; + i_tpmBuf = NULL; + break; + } + memcpy(&val->event, i_tpmBuf, size); + i_tpmBuf += size; + } while(0); + + return i_tpmBuf; + } + size_t TPM_EVENT_FIELD_marshalSize(const TPM_EVENT_FIELD* val) + { + return (sizeof(val->eventSize) + val->eventSize); + } + + +#ifdef __cplusplus + bool TPM_EVENT_FIELD::operator==(const TPM_EVENT_FIELD& i_rhs) const + { + return (eventSize == i_rhs.eventSize) && + (memcmp(event, i_rhs.event, eventSize) == 0); + } +#endif + + + size_t TCG_PCR_EVENT2_marshalSize(const TCG_PCR_EVENT2* val) + { + return (sizeof(val->pcrIndex) + sizeof(val->eventType) + + TPML_DIGEST_VALUES_marshalSize(&(val->digests)) + + TPM_EVENT_FIELD_marshalSize(&(val->event))); + } + + uint8_t* TCG_PCR_EVENT2_logMarshal(const TCG_PCR_EVENT2* val, + uint8_t* i_logBuf) + { + uint32_t* field32 = (uint32_t*)i_logBuf; + *field32 = htole32(val->pcrIndex); + i_logBuf += sizeof(uint32_t); + field32 = (uint32_t*)i_logBuf; + *field32 = htole32(val->eventType); + i_logBuf += sizeof(uint32_t); + + i_logBuf = TPML_DIGEST_VALUES_logMarshal(&(val->digests),i_logBuf); + if (NULL != i_logBuf) + { + i_logBuf = TPM_EVENT_FIELD_logMarshal(&(val->event),i_logBuf); + } + return i_logBuf; + } + + const uint8_t* TCG_PCR_EVENT2_logUnmarshal(TCG_PCR_EVENT2* val, + const uint8_t* i_tpmBuf, + size_t i_bufSize, + bool* o_err) + { + size_t size = 0; + uint32_t* field32 = NULL; + + do { + *o_err = false; + + // Ensure enough space for unmarshalled data + if (sizeof(TCG_PCR_EVENT2) > i_bufSize) + { + *o_err = true; + i_tpmBuf = NULL; + break; + } + + // pcrIndex + size = sizeof(val->pcrIndex); + field32 = (uint32_t*)(i_tpmBuf); + val->pcrIndex = le32toh(*field32); + // Ensure a valid pcr index + if (val->pcrIndex > IMPLEMENTATION_PCR) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:" + "logUnmarshal() invalid pcrIndex %d", + val->pcrIndex); + break; + } + i_tpmBuf += size; + + // eventType + size = sizeof(val->eventType); + field32 = (uint32_t*)(i_tpmBuf); + val->eventType = le32toh(*field32); + // Ensure a valid event type + if (val->eventType == 0 || + val->eventType >= EV_INVALID) + { + *o_err = true; + i_tpmBuf = NULL; + TRACFCOMP(g_trac_trustedboot,"ERROR> TCG_PCR_EVENT2:" + "logUnmarshal() invalid eventType %d", + val->eventType); + break; + } + i_tpmBuf += size; + + // TPML_DIGEST_VALUES + i_tpmBuf = TPML_DIGEST_VALUES_logUnmarshal(&(val->digests), + i_tpmBuf, o_err); + if (i_tpmBuf == NULL) + { + break; + } + + // TPM EVENT FIELD + i_tpmBuf = TPM_EVENT_FIELD_logUnmarshal(&(val->event), + i_tpmBuf, o_err); + if (i_tpmBuf == NULL) + { + break; + } + } while(0); + + return i_tpmBuf; + } + +#ifdef __cplusplus + bool TCG_PCR_EVENT2::operator==(const TCG_PCR_EVENT2& i_rhs) const + { + return (pcrIndex == i_rhs.pcrIndex) && + (eventType == i_rhs.eventType) && + (digests == i_rhs.digests) && + (event == i_rhs.event); + } } // end TRUSTEDBOOT #endif diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index 936217226..096bc1c57 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -42,12 +42,14 @@ #include #include #include +#include +#include #include "trustedboot.H" #include "trustedTypes.H" #include "trustedbootCmds.H" #include "trustedbootUtils.H" -#include "base/tpmLogMgr.H" -#include "base/trustedboot_base.H" +#include "tpmLogMgr.H" +#include "base/trustedbootMsg.H" #include "../settings.H" namespace TRUSTEDBOOT @@ -197,13 +199,6 @@ void* host_update_master_tpm( void *io_pArgs ) } } - // Now we need to replay any existing entries in the log into the TPM - if (!systemTpms.tpm[TPM_MASTER_INDEX].failed && - systemTpms.tpm[TPM_MASTER_INDEX].available) - { - tpmReplayLog(systemTpms.tpm[TPM_MASTER_INDEX]); - } - if (systemTpms.tpm[TPM_MASTER_INDEX].failed || !systemTpms.tpm[TPM_MASTER_INDEX].available) { @@ -268,6 +263,12 @@ void* host_update_master_tpm( void *io_pArgs ) mutex_unlock(&(systemTpms.tpm[TPM_MASTER_INDEX].tpmMutex)); } + if (NULL == err) + { + // Start the task to start to handle the message queue/extends + task_create(&TRUSTEDBOOT::tpmDaemon, NULL); + } + if (NULL == err) { // Log config entries to TPM - needs to be after mutex_unlock @@ -413,7 +414,7 @@ void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target) errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) { - TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmLogConfigEntries()"); + TRACUCOMP(g_trac_trustedboot, ENTER_MRK"tpmLogConfigEntries()"); errlHndl_t l_err = NULL; @@ -487,4 +488,268 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) return l_err; } +void pcrExtendSingleTpm(TpmTarget & io_target, + TPM_Pcr i_pcr, + TPM_Alg_Id i_algId, + const uint8_t* i_digest, + size_t i_digestSize, + const char* i_logMsg) +{ + errlHndl_t err = NULL; + TCG_PCR_EVENT2 eventLog; + bool unlock = false; + + memset(&eventLog, 0, sizeof(eventLog)); + do + { + mutex_lock( &io_target.tpmMutex ); + unlock = true; + + // Allocate the TPM log if it hasn't been already + if (!io_target.failed && + io_target.available && + NULL == io_target.logMgr) + { + io_target.logMgr = new TpmLogMgr; + err = TpmLogMgr_initialize(io_target.logMgr); + if (NULL != err) + { + break; + } + } + + // Log the event, we will do this in two scenarios + // - !initAttempted - prior to IPL of the TPM we log for replay + // - initAttempted && !failed - TPM is functional so we log + if ((io_target.available && + !io_target.initAttempted) || + (io_target.available && + io_target.initAttempted && + !io_target.failed)) + { + // Fill in TCG_PCR_EVENT2 and add to log + eventLog = TpmLogMgr_genLogEventPcrExtend(i_pcr, i_algId, i_digest, + i_digestSize, i_logMsg); + err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog); + if (NULL != err) + { + break; + } + } + + // If the TPM init has occurred and it is currently + // functional we will do our extension + if (io_target.available && + io_target.initAttempted && + !io_target.failed) + { + + err = tpmCmdPcrExtend(&io_target, + i_pcr, + i_algId, + i_digest, + i_digestSize); + } + } while ( 0 ); + + if (NULL != err) + { + // We failed to extend to this TPM we can no longer use it + tpmMarkFailed(&io_target); + + // Log this failure + errlCommit(err, SECURE_COMP_ID); + err = NULL; + } + + if (unlock) + { + mutex_unlock(&io_target.tpmMutex); + } + return; +} + +void tpmMarkFailed(TpmTarget * io_target) +{ + + TRACFCOMP( g_trac_trustedboot, + ENTER_MRK"tpmMarkFailed() Marking TPM as failed : " + "tgt=0x%X chip=%d", + TARGETING::get_huid(io_target->nodeTarget), + io_target->chip); + + io_target->failed = true; + /// @todo RTC:125287 Add fail marker to TPM log and disable TPM access + +} + +errlHndl_t tpmVerifyFunctionalTpmExists() +{ + errlHndl_t err = NULL; + bool foundFunctional = false; + + for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++) + { + if ((!systemTpms.tpm[idx].failed && systemTpms.tpm[idx].available) || + !systemTpms.tpm[idx].initAttempted) + { + foundFunctional = true; + break; + } + } + + if (!foundFunctional) + { + TRACFCOMP( g_trac_trustedboot, + "NO FUNCTIONAL TPM FOUND"); + + /*@ + * @errortype + * @reasoncode RC_TPM_NOFUNCTIONALTPM_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_VERIFYFUNCTIONAL + * @userdata1 0 + * @userdata2 0 + * @devdesc No functional TPMs exist in the system + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_VERIFYFUNCTIONAL, + RC_TPM_NOFUNCTIONALTPM_FAIL, + 0, 0, + true /*Add HB SW Callout*/ ); + + err->collectTrace( SECURE_COMP_NAME ); + + } + + return err; +} + + +void* tpmDaemon(void* unused) +{ + bool shutdownPending = false; + errlHndl_t err = NULL; + + // Mark as an independent daemon so if it crashes we terminate + task_detach(); + + TRACUCOMP( g_trac_trustedboot, ENTER_MRK "TpmDaemon Thread Start"); + + // Register shutdown events with init service. + // Done at the "end" of shutdown processing. + // This will flush any other messages (PCR extends) and terminate task + INITSERVICE::registerShutdownEvent(systemTpms.msgQ, + TRUSTEDBOOT::MSG_TYPE_SHUTDOWN); + + Message* tb_msg = NULL; + while (true) + { + msg_t* msg = msg_wait(systemTpms.msgQ); + + const MessageType type = + static_cast(msg->type); + tb_msg = NULL; + + TRACUCOMP( g_trac_trustedboot, "TpmDaemon Handle CmdType %d", + type); + + switch (type) + { + case TRUSTEDBOOT::MSG_TYPE_SHUTDOWN: + { + shutdownPending = true; + } + break; + case TRUSTEDBOOT::MSG_TYPE_PCREXTEND: + { + tb_msg = static_cast(msg->extra_data); + + TRUSTEDBOOT::PcrExtendMsgData* msgData = + reinterpret_cast + (tb_msg->iv_data); + + assert(tb_msg->iv_len == sizeof(TRUSTEDBOOT::PcrExtendMsgData) + && msgData != NULL, "Invalid PCRExtend Message"); + + for (size_t idx = 0; + idx < TRUSTEDBOOT::MAX_SYSTEM_TPMS; idx++) + { + // Add the event to this TPM, + // if an error occurs the TPM will + // be marked as failed and the error log committed + TRUSTEDBOOT::pcrExtendSingleTpm( + TRUSTEDBOOT::systemTpms.tpm[idx], + msgData->mPcrIndex, + msgData->mAlgId, + msgData->mDigest, + msgData->mDigestSize, + msgData->mLogMsg); + } + + if (TRUSTEDBOOT::MSG_MODE_SYNC == tb_msg->iv_mode) + { + // Lastly make sure we are in a state + // where we have a functional TPM + // Only do for sync messages that will actually + // get the error log back + tb_msg->iv_errl = + TRUSTEDBOOT::tpmVerifyFunctionalTpmExists(); + } + } + break; + + default: + assert(false, "Invalid msg command"); + break; + }; + + // Reply back, if we have a tb_msg do that way + if (NULL != tb_msg) + { + tb_msg->response(systemTpms.msgQ); + } + else + { + // use the HB message type to respond + int rc = msg_respond(systemTpms.msgQ, msg); + if (rc) + { + TRACFCOMP( g_trac_trustedboot, + ERR_MRK "TpmDaemon: response msg_respond failure %d", + rc); + /*@ + * @errortype ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_TPMDAEMON + * @reasoncode RC_MSGRESPOND_FAIL + * @userdata1 rc from msq_respond() + * @devdesc msg_respond() failed + * @custdesc Firmware error during system boot + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_TPMDAEMON, + RC_MSGRESPOND_FAIL, + rc, + 0, + true); + err->collectTrace(SECURE_COMP_NAME); + + // Log this failure here since we can't reply to caller + errlCommit(err, SECURE_COMP_ID); + + } + } + + if (shutdownPending) + { + // Exit loop and terminate task + break; + } + } + // Daemon is shutting down we can't handle any requests after this + systemTpms.tpmDaemonShutdown = true; + TRACUCOMP( g_trac_trustedboot, EXIT_MRK "TpmDaemon Thread Terminate"); + return NULL; +} + } // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H index 866e253e5..ad15ff8bc 100644 --- a/src/usr/secureboot/trusted/trustedboot.H +++ b/src/usr/secureboot/trusted/trustedboot.H @@ -36,6 +36,7 @@ #include #include #include +#include #include "trustedTypes.H" // ---------------------------------------------- @@ -58,8 +59,14 @@ namespace TRUSTEDBOOT class SystemTpms { public: - SystemTpms(); + SystemTpms(): + msgQ(msg_q_create()), + tpmDaemonShutdown(false) + { } + + msg_q_t msgQ; ///< TrustedBootRp message queue + bool tpmDaemonShutdown; ///< Has the TPM Daemon already been shutdown TpmTarget tpm[MAX_SYSTEM_TPMS]; }; @@ -97,5 +104,43 @@ void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target); */ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target); + +/** + * @brief Verify a functional TPM still exists in the system + * @return errlHndl_t NULL if TPM available, otherwise a pointer to the + * error log. +*/ +errlHndl_t tpmVerifyFunctionalTpmExists(); + +/** + * @brief Extend a measurement into a TPM and log + * @param[in/out] io_target Current TPM target structure + * @param[in] i_pcr PCR to write to + * @param[in] i_algId Algorithm to extend + * @param[in] i_digest Digest value to write to PCR + * @param[in] i_digestSize Byte size of i_digest data + * @param[in] i_logMsg Null terminated log message + */ +void pcrExtendSingleTpm(TpmTarget & io_target, + TPM_Pcr i_pcr, + TPM_Alg_Id i_algId, + const uint8_t* i_digest, + size_t i_digestSize, + const char* i_logMsg); + + +/** + * @brief Is the TPM_REQUIRED flag set such that the + * system should not boot without a functional TPM + * @retval true TPM is required to boot + * @retval false TPM is not required, failures should be logged + */ +bool isTpmRequired(); + +/** Thread start routine for the TPM Daemon + * @param[in] void*, unused + */ +void* tpmDaemon(void* unused); + } // end TRUSTEDBOOT namespace #endif diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C index 62fec182b..1bc8b8945 100644 --- a/src/usr/secureboot/trusted/trustedbootCmds.C +++ b/src/usr/secureboot/trusted/trustedbootCmds.C @@ -722,7 +722,7 @@ errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target) errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target, TPM_Pcr i_pcr, TPM_Alg_Id i_algId, - uint8_t* i_digest, + const uint8_t* i_digest, size_t i_digestSize) { errlHndl_t err = NULL; @@ -749,7 +749,6 @@ errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target, // Argument verification if (fullDigestSize == 0 || - fullDigestSize != i_digestSize || NULL == i_digest || IMPLEMENTATION_PCR < i_pcr ) @@ -784,7 +783,8 @@ errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target, cmd->pcrHandle = i_pcr; cmd->digests.count = 1; cmd->digests.digests[0].algorithmId = i_algId; - memcpy(cmd->digests.digests[0].digest.bytes, i_digest, fullDigestSize); + memcpy(cmd->digests.digests[0].digest.bytes, i_digest, + (i_digestSize < fullDigestSize ? i_digestSize : fullDigestSize)); err = tpmTransmitCommand(io_target, dataBuf, diff --git a/src/usr/secureboot/trusted/trustedbootCmds.H b/src/usr/secureboot/trusted/trustedbootCmds.H index 53c7f453e..ffabd3440 100644 --- a/src/usr/secureboot/trusted/trustedbootCmds.H +++ b/src/usr/secureboot/trusted/trustedbootCmds.H @@ -125,7 +125,7 @@ errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target); errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target, TPM_Pcr i_pcr, TPM_Alg_Id i_algId, - uint8_t* i_digest, + const uint8_t* i_digest, size_t i_digestSize); /** diff --git a/src/usr/secureboot/trusted/trustedbootUtils.C b/src/usr/secureboot/trusted/trustedbootUtils.C index 25cd56e03..5f140382c 100644 --- a/src/usr/secureboot/trusted/trustedbootUtils.C +++ b/src/usr/secureboot/trusted/trustedbootUtils.C @@ -80,8 +80,19 @@ errlHndl_t tpmTransmit(TpmTarget * io_target, return err; } +errlHndl_t tpmCreateErrorLog(const uint8_t i_modId, + const uint16_t i_reasonCode, + const uint64_t i_user1, + const uint64_t i_user2) +{ + errlHndl_t err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + i_modId, + i_reasonCode, + i_user1, + i_user2, + true /*Add HB SW Callout*/ ); + err->collectTrace( SECURE_COMP_NAME ); + return err; +} - -#ifdef __cplusplus } // end TRUSTEDBOOT -#endif -- cgit v1.2.3