diff options
| author | Chris Engel <cjengel@us.ibm.com> | 2015-08-25 09:37:28 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-03-15 16:46:13 -0400 |
| commit | e09fae967685172091f4b90657dacd4a0c5a1e5c (patch) | |
| tree | f7bfaded7697b23093300d9aa6ccdada85c6ac8b /src/usr/secureboot/trusted/base | |
| parent | f52d668fcefa6e35650aa8eab78b5405b0612992 (diff) | |
| download | talos-hostboot-e09fae967685172091f4b90657dacd4a0c5a1e5c.tar.gz talos-hostboot-e09fae967685172091f4b90657dacd4a0c5a1e5c.zip | |
Trustedboot TPM Event log manager
Change-Id: I4a8c2010421a63e44112666bdd424e2e5d010e7f
RTC: 125289
ForwardPort: yes
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/960
Tested-by: Jenkins Server
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Reviewed-by: Timothy R. Block <block@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22009
Diffstat (limited to 'src/usr/secureboot/trusted/base')
| -rw-r--r-- | src/usr/secureboot/trusted/base/tpmLogMgr.C | 254 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/tpmLogMgr.H | 130 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedTypes_base.C | 261 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 208 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.H | 67 |
5 files changed, 918 insertions, 2 deletions
diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.C b/src/usr/secureboot/trusted/base/tpmLogMgr.C new file mode 100644 index 000000000..400ecfe17 --- /dev/null +++ b/src/usr/secureboot/trusted/base/tpmLogMgr.C @@ -0,0 +1,254 @@ +/* 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 <string.h> +#include "tpmLogMgr.H" +#ifdef __HOSTBOOT_MODULE +#include <secureboot/trustedboot_reasoncodes.H> +#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); + } + + 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 + { + + val->logSize = 0; + 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, + "<<initialize() LS:%d - %s", + val->logSize, + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + } + + 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); + uint8_t* startPtr = val->newEventPtr; + + 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 > TPMLOG_BUFFER_SIZE) + { + TRACFCOMP( g_trac_trustedboot, + "TPM LOG ADD FAIL PNULL(%d) LS(%d) New LS(%d)", + (NULL == val->newEventPtr ? 0 : 1), + (int)val->logSize, (int)newLogSize); + + /*@ + * @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; + } + + // Debug display of raw data + TRACUCOMP(g_trac_trustedboot, "tpmAddEvent: Start %p", + startPtr); + TRACUBIN(g_trac_trustedboot, "tpmAddEvent", + startPtr, newLogSize); + + + val->logSize += newLogSize; + + + } while ( 0 ); + + TRACUCOMP( g_trac_trustedboot, + "<<tpmAddEvent() LS:%d - %s", + (int)val->logSize, + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + + mutex_unlock( &val->logMutex ); + return err; + } + + uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val) + { + return val->logSize; + } + + void TpmLogMgr_dumpLog(TpmLogMgr* val) + { + + // Debug display of raw data + TRACUCOMP(g_trac_trustedboot, "tpmDumpLog Size : %d\n", + (int)val->logSize); + TRACUBIN(g_trac_trustedboot, "tpmDumpLog", + val->eventLog, val->logSize); + } + +#ifdef __cplusplus +} // end TRUSTEDBOOT +#endif diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.H b/src/usr/secureboot/trusted/base/tpmLogMgr.H new file mode 100644 index 000000000..f56e27d7b --- /dev/null +++ b/src/usr/secureboot/trusted/base/tpmLogMgr.H @@ -0,0 +1,130 @@ +/* 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 <sys/sync.h> +#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 + }; + + struct _TpmLogMgr + { + uint32_t logSize; ///< Current byte size of log + uint8_t eventLog[TPMLOG_BUFFER_SIZE]; ///< EventLog Buffer + uint8_t* newEventPtr; ///< Pointer to location to add new event + mutex_t logMutex; ///< Log mutex + }; + typedef struct _TpmLogMgr TpmLogMgr; + + /** + * @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); + + /** + * @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); + + /** + * @brief Dump contents of log to a trace + * @param[in] val TpmLogMgr structure + */ + void TpmLogMgr_dumpLog(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 new file mode 100644 index 000000000..3c3d8d737 --- /dev/null +++ b/src/usr/secureboot/trusted/base/trustedTypes_base.C @@ -0,0 +1,261 @@ +/* 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 <string.h> +#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(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; + } + + size_t TPML_DIGEST_VALUES_marshalSize(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(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; + } + + uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val, + 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 >= PCR_MAX) + { + *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(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; + } + + + uint8_t* TPM_EVENT_FIELD_logMarshal(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; + } + + size_t TCG_PCR_EVENT2_marshalSize(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(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; + } + +#ifdef __cplusplus +} // end TRUSTEDBOOT +#endif diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C index 31522ef7f..e9f20db59 100644 --- a/src/usr/secureboot/trusted/base/trustedboot_base.C +++ b/src/usr/secureboot/trusted/base/trustedboot_base.C @@ -26,6 +26,7 @@ * @file trustedboot_base.C * * @brief Trusted boot base interfaces + * This file is compiled in regardless of CONFIG_TPMDD */ // ---------------------------------------------- @@ -39,8 +40,11 @@ #include <errl/errludtarget.H> #include <errl/errludstring.H> #include <secureboot/trustedbootif.H> -#include "../trustedboot.H" #include <secureboot/trustedboot_reasoncodes.H> +#include "trustedboot_base.H" +#include "../trustedboot.H" +#include "../trustedbootUtils.H" +#include "tpmLogMgr.H" // ---------------------------------------------- // Trace definitions @@ -53,6 +57,7 @@ TRAC_INIT( & g_trac_trustedboot, "TRBOOT", KILOBYTE ); namespace TRUSTEDBOOT { +#ifdef CONFIG_TPMDD /// Global object to store TPM status SystemTpms systemTpms; @@ -65,7 +70,10 @@ TpmTarget::TpmTarget() memset(this, 0, sizeof(TpmTarget)); available = true; // Default to available until we know better mutex_init(&tpmMutex); + } +#endif + errlHndl_t pcrExtend(TPM_Pcr i_pcr, uint8_t* i_digest, @@ -74,10 +82,206 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr, { errlHndl_t err = NULL; #ifdef CONFIG_TPMDD - /// @todo RTC:125288 Add call to extend the PCR + TPM_Alg_Id algId = TPM_ALG_SHA256; + + size_t fullDigestSize = getDigestSize(algId); + char logMsg[MAX_TPM_LOG_MSG]; + + TRACDCOMP( g_trac_trustedboot, + ENTER_MRK"pcrExtend()" ); + TRACUCOMP( g_trac_trustedboot, + ENTER_MRK"pcrExtend() pcr=%d msg='%s' digest=%016llX", + i_pcr, + i_logMsg, + *(reinterpret_cast<uint64_t*>(i_digest))); + + // Ensure proper digest size + uint8_t digestData[fullDigestSize]; + memset(digestData, 0, sizeof(digestData)); + + // 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)); + + for (size_t idx = 0; idx < 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 + pcrExtendSingleTpm(systemTpms.tpm[idx], + i_pcr, + algId, + digestData, + fullDigestSize, + logMsg); + } + + + // 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; + + 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; + } + } + + + + // 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) + { + + /// @todo RTC:125288 Add call to extend the PCR + } + + // Now we 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)) + { + 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); + + // Event field data + eventLog.event.eventSize = strlen(i_logMsg); + assert(eventLog.event.eventSize <= MAX_TPM_LOG_MSG, + "TPM Log message too long"); + memcpy(eventLog.event.event, i_logMsg, strlen(i_logMsg)); + + err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog); + if (NULL != err) + { + break; + } + } + + } 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].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; +} +#endif + } // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.H b/src/usr/secureboot/trusted/base/trustedboot_base.H new file mode 100644 index 000000000..70d160b02 --- /dev/null +++ b/src/usr/secureboot/trusted/base/trustedboot_base.H @@ -0,0 +1,67 @@ +/* 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 <secureboot/trustedbootif.H> +#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 |

