summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris Engel <cjengel@us.ibm.com>2016-06-03 16:44:29 -0500
committerStephen Cprek <smcprek@us.ibm.com>2016-07-18 15:32:39 -0500
commit661c7e6a3ef2f76bfce68cb67f2f6d2d1c3d6f9b (patch)
tree33373da8433aae14fca1fb58a141cc0402d072c6 /src
parentb3f6347ef52994c4d37ac5f361b21fe4d4658462 (diff)
downloadtalos-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')
-rw-r--r--src/include/usr/secureboot/trustedboot_reasoncodes.H6
-rw-r--r--src/include/usr/secureboot/trustedbootif.H6
-rw-r--r--src/usr/devtree/bld_devtree.C2
-rw-r--r--src/usr/ipmi/ipmimsg.C4
-rw-r--r--src/usr/secureboot/base/makefile3
-rw-r--r--src/usr/secureboot/trusted/base/trustedTypes_base.C504
-rw-r--r--src/usr/secureboot/trusted/base/trustedbootMsg.C132
-rw-r--r--src/usr/secureboot/trusted/base/trustedbootMsg.H174
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C263
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.H67
-rw-r--r--src/usr/secureboot/trusted/makefile1
-rwxr-xr-xsrc/usr/secureboot/trusted/test/tpmLogMgrTest.H2
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H3
-rw-r--r--src/usr/secureboot/trusted/tpmLogMgr.C (renamed from src/usr/secureboot/trusted/base/tpmLogMgr.C)10
-rw-r--r--src/usr/secureboot/trusted/tpmLogMgr.H (renamed from src/usr/secureboot/trusted/base/tpmLogMgr.H)7
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.C453
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C285
-rw-r--r--src/usr/secureboot/trusted/trustedboot.H47
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C6
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.H2
-rw-r--r--src/usr/secureboot/trusted/trustedbootUtils.C17
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
OpenPOWER on IntegriCloud