diff options
author | Chris Engel <cjengel@us.ibm.com> | 2016-06-03 16:44:29 -0500 |
---|---|---|
committer | Stephen Cprek <smcprek@us.ibm.com> | 2016-07-18 15:32:39 -0500 |
commit | 661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b (patch) | |
tree | 33373da8433aae14fca1fb58a141cc0402d072c6 /src | |
parent | b3f6347ef52994c4d37ac5f361b21fe4d4658462 (diff) | |
download | talos-hostboot-661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b.tar.gz talos-hostboot-661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b.zip |
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 <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
21 files changed, 1200 insertions, 794 deletions
diff --git a/src/include/usr/secureboot/trustedboot_reasoncodes.H b/src/include/usr/secureboot/trustedboot_reasoncodes.H index 902b1cb26..bc2031080 100644 --- a/src/include/usr/secureboot/trustedboot_reasoncodes.H +++ b/src/include/usr/secureboot/trustedboot_reasoncodes.H @@ -53,6 +53,9 @@ namespace TRUSTEDBOOT MOD_TPM_CMD_PCREXTEND = 0x07, MOD_TPM_CMD_PCRREAD = 0x08, MOD_TPM_REPLAY_LOG = 0x09, + MOD_TPM_PCREXTEND = 0x0A, + MOD_TPM_TPMDAEMON = 0x0B, + MOD_TPM_SYNCRESPONSE = 0x0C, MOD_TPMLOGMGR_INITIALIZE = 0x10, MOD_TPMLOGMGR_ADDEVENT = 0x11, @@ -81,6 +84,9 @@ namespace TRUSTEDBOOT RC_TPM_COMMAND_FAIL = SECURE_COMP_ID | 0xAE, RC_TPM_INVALID_ARGS = SECURE_COMP_ID | 0xAF, RC_TPMLOGMGR_LOGWALKFAIL = SECURE_COMP_ID | 0xB0, + RC_PCREXTEND_SENDRECV_FAIL = SECURE_COMP_ID | 0xB1, + RC_PCREXTEND_SEND_FAIL = SECURE_COMP_ID | 0xB2, + RC_MSGRESPOND_FAIL = SECURE_COMP_ID | 0xB3, }; #ifdef __cplusplus } diff --git a/src/include/usr/secureboot/trustedbootif.H b/src/include/usr/secureboot/trustedbootif.H index 437227d36..27dd1e8d4 100644 --- a/src/include/usr/secureboot/trustedbootif.H +++ b/src/include/usr/secureboot/trustedbootif.H @@ -86,15 +86,17 @@ namespace TRUSTEDBOOT * @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, truncated at 128 chars + * @param[in] i_sendAsync Perform extension asynchronously, default true * @return errlHndl_t NULL if successful, otherwise a pointer to the * error log. * Digest will be right padded with zeros or truncated to match TPM digest * size being used */ 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 = true); /** * @brief Return a set of information related to every unique diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C index d7986e9ee..dca41c68f 100644 --- a/src/usr/devtree/bld_devtree.C +++ b/src/usr/devtree/bld_devtree.C @@ -2289,7 +2289,7 @@ errlHndl_t bld_fdt_secureboot(devTree * i_dt, bool i_smallTree) i_dt->addPropertyString(secBootNode, "hash-algo", "sha512"); /* compatibility strings -- currently only one */ - const char* compatStr[] = {"ibm,power-secureboot-v1", NULL}; + const char* compatStr[] = {"ibm,secureboot-v1", NULL}; i_dt->addPropertyStrings(secBootNode, "compatible", compatStr); if (SECUREBOOT::enabled()) diff --git a/src/usr/ipmi/ipmimsg.C b/src/usr/ipmi/ipmimsg.C index c41fa0528..24673e043 100644 --- a/src/usr/ipmi/ipmimsg.C +++ b/src/usr/ipmi/ipmimsg.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -23,7 +23,7 @@ /* */ /* IBM_PROLOG_END_TAG */ /** - * @file ipmi.C + * @file ipmimsg.C * @brief code for the IPMI message class */ 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/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 <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(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 <sys/msg.h> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <secureboot/trustedboot_reasoncodes.H> +#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<void*>(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 <errl/errlentry.H> +#include <sys/msg.h> +#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 <string.h> #include <sys/time.h> +#include <sys/msg.h> #include <trace/interface.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> @@ -41,11 +42,10 @@ #include <errl/errludstring.H> #include <secureboot/trustedbootif.H> #include <secureboot/trustedboot_reasoncodes.H> -#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<uint8_t*>(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 <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 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 <errl/errlmanager.H> #include <errl/errlentry.H> #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/base/tpmLogMgr.C b/src/usr/secureboot/trusted/tpmLogMgr.C index d129bbaa1..f5ab74a64 100644 --- a/src/usr/secureboot/trusted/base/tpmLogMgr.C +++ b/src/usr/secureboot/trusted/tpmLogMgr.C @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/secureboot/trusted/base/tpmLogMgr.C $ */ +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -41,14 +41,12 @@ #include <sys/mm.h> #include <util/align.H> #include <secureboot/trustedboot_reasoncodes.H> -#include "../trustedbootUtils.H" -#include "../trustedboot.H" #else #include "trustedboot_reasoncodes.H" +#endif #include "trustedbootUtils.H" #include "trustedboot.H" #include "trustedTypes.H" -#endif #ifdef __cplusplus namespace TRUSTEDBOOT @@ -473,9 +471,11 @@ namespace TRUSTEDBOOT // 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 : strlen(i_logMsg)) ); + MAX_TPM_LOG_MSG - 1 // Leave room for NULL termination + : strlen(i_logMsg)) ); return eventLog; } diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.H b/src/usr/secureboot/trusted/tpmLogMgr.H index b12f5cb15..15dd6e653 100644 --- a/src/usr/secureboot/trusted/base/tpmLogMgr.H +++ b/src/usr/secureboot/trusted/tpmLogMgr.H @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/secureboot/trusted/base/tpmLogMgr.H $ */ +/* $Source: src/usr/secureboot/trusted/tpmLogMgr.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -41,12 +41,9 @@ #ifdef __HOSTBOOT_MODULE #include <sys/sync.h> -#include "../trustedboot.H" -#include "../trustedTypes.H" -#else +#endif #include "trustedboot.H" #include "trustedTypes.H" -#endif #ifdef __cplusplus namespace TRUSTEDBOOT 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 <secureboot/trustedbootif.H> #include <secureboot/trustedboot_reasoncodes.H> #include <sys/mmio.h> +#include <sys/task.h> +#include <initservice/initserviceif.H> #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) { @@ -270,6 +265,12 @@ void* host_update_master_tpm( void *io_pArgs ) 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 err = tpmLogConfigEntries(systemTpms.tpm[TPM_MASTER_INDEX]); } @@ -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<MessageType>(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<TRUSTEDBOOT::Message*>(msg->extra_data); + + TRUSTEDBOOT::PcrExtendMsgData* msgData = + reinterpret_cast<TRUSTEDBOOT::PcrExtendMsgData*> + (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 <secureboot/trustedbootif.H> #include <i2c/tpmddif.H> #include <trace/interface.H> +#include <sys/msg.h> #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 |