summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted/base
diff options
context:
space:
mode:
authorChris Engel <cjengel@us.ibm.com>2015-08-25 09:37:28 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-03-15 16:46:13 -0400
commite09fae967685172091f4b90657dacd4a0c5a1e5c (patch)
treef7bfaded7697b23093300d9aa6ccdada85c6ac8b /src/usr/secureboot/trusted/base
parentf52d668fcefa6e35650aa8eab78b5405b0612992 (diff)
downloadtalos-hostboot-e09fae967685172091f4b90657dacd4a0c5a1e5c.tar.gz
talos-hostboot-e09fae967685172091f4b90657dacd4a0c5a1e5c.zip
Trustedboot TPM Event log manager
Change-Id: I4a8c2010421a63e44112666bdd424e2e5d010e7f RTC: 125289 ForwardPort: yes Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/960 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Timothy R. Block <block@us.ibm.com> Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22009
Diffstat (limited to 'src/usr/secureboot/trusted/base')
-rw-r--r--src/usr/secureboot/trusted/base/tpmLogMgr.C254
-rw-r--r--src/usr/secureboot/trusted/base/tpmLogMgr.H130
-rw-r--r--src/usr/secureboot/trusted/base/trustedTypes_base.C261
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C208
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.H67
5 files changed, 918 insertions, 2 deletions
diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.C b/src/usr/secureboot/trusted/base/tpmLogMgr.C
new file mode 100644
index 000000000..400ecfe17
--- /dev/null
+++ b/src/usr/secureboot/trusted/base/tpmLogMgr.C
@@ -0,0 +1,254 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/base/tpmLogMgr.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file TpmLogMgr.C
+ *
+ * @brief TPM Event log manager
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include "tpmLogMgr.H"
+#ifdef __HOSTBOOT_MODULE
+#include <secureboot/trustedboot_reasoncodes.H>
+#include "../trustedbootUtils.H"
+#include "../trustedboot.H"
+#else
+#include "trustedboot_reasoncodes.H"
+#include "trustedbootUtils.H"
+#include "trustedboot.H"
+#include "trustedTypes.H"
+#endif
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val)
+ {
+ return (sizeof(TCG_EfiSpecIdEventStruct) + val->vendorInfoSize);
+ }
+
+ errlHndl_t TpmLogMgr_initialize(TpmLogMgr* val)
+ {
+ errlHndl_t err = TB_SUCCESS;
+ const char vendorInfo[] = "IBM";
+ const char eventSignature[] = "Spec ID Event03";
+ TCG_EfiSpecIdEventStruct* eventData = NULL;
+
+ TCG_PCR_EVENT eventLogEntry;
+
+ TRACUCOMP( g_trac_trustedboot, ">>initialize()");
+
+ if (NULL == val)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM LOG INIT FAIL");
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPMLOGMGR_INIT_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPMLOGMGR_INITIALIZE
+ * @userdata1 0
+ * @userdata2 0
+ * @devdesc TPM log buffer init failure.
+ */
+ err = tpmCreateErrorLog( MOD_TPMLOGMGR_INITIALIZE,
+ RC_TPMLOGMGR_INIT_FAIL, 0, 0);
+
+ }
+ else
+ {
+
+ val->logSize = 0;
+ mutex_init( &val->logMutex );
+ mutex_lock( &val->logMutex );
+
+
+ // Assign our new event pointer to the start
+ val->newEventPtr = val->eventLog;
+ memset(val->eventLog, 0, TPMLOG_BUFFER_SIZE);
+
+ eventData = (TCG_EfiSpecIdEventStruct*) eventLogEntry.event;
+
+ // Add the header event log
+ // Values here come from the PC ClientSpecificPlatformProfile spec
+ eventLogEntry.eventType = EV_NO_ACTION;
+ eventLogEntry.pcrIndex = 0;
+ eventLogEntry.eventSize = sizeof(TCG_EfiSpecIdEventStruct) +
+ sizeof(vendorInfo);
+
+ memcpy(eventData->signature, eventSignature,
+ sizeof(eventSignature));
+ eventData->platformClass = htole32(TPM_PLATFORM_SERVER);
+ eventData->specVersionMinor = TPM_SPEC_MINOR;
+ eventData->specVersionMajor = TPM_SPEC_MAJOR;
+ eventData->specErrata = TPM_SPEC_ERRATA;
+ eventData->uintnSize = 1;
+ eventData->numberOfAlgorithms = htole32(HASH_COUNT);
+ eventData->digestSizes[0].algorithmId = htole16(TPM_ALG_SHA256);
+ eventData->digestSizes[0].digestSize = htole16(TPM_ALG_SHA256_SIZE);
+ eventData->vendorInfoSize = sizeof(vendorInfo);
+ memcpy(eventData->vendorInfo, vendorInfo, sizeof(vendorInfo));
+
+ val->newEventPtr = TCG_PCR_EVENT_logMarshal(&eventLogEntry,
+ val->newEventPtr);
+
+ // Done, move our pointers
+ val->logSize += TCG_PCR_EVENT_marshalSize(&eventLogEntry);
+
+
+ mutex_unlock( &val->logMutex );
+
+ // Debug display of raw data
+ TRACUBIN(g_trac_trustedboot, "tpmInitialize: Header Entry",
+ val->eventLog, val->logSize);
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<initialize() LS:%d - %s",
+ val->logSize,
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ }
+
+ return err;
+ }
+
+ errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val,
+ TCG_PCR_EVENT2* logEvent)
+ {
+ errlHndl_t err = TB_SUCCESS;
+ size_t newLogSize = TCG_PCR_EVENT2_marshalSize(logEvent);
+ uint8_t* startPtr = val->newEventPtr;
+
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmAddEvent() PCR:%d Type:%d Size:%d",
+ logEvent->pcrIndex, logEvent->eventType, (int)newLogSize);
+
+ mutex_lock( &val->logMutex );
+
+ do
+ {
+
+ // Need to ensure we have room for the new event
+ // We have to leave room for the log full event as well
+ if (NULL == val->newEventPtr ||
+ val->logSize + newLogSize > TPMLOG_BUFFER_SIZE)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM LOG ADD FAIL PNULL(%d) LS(%d) New LS(%d)",
+ (NULL == val->newEventPtr ? 0 : 1),
+ (int)val->logSize, (int)newLogSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPMLOGMGR_ADDEVENT_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPMLOGMGR_ADDEVENT
+ * @userdata1 Log buffer NULL
+ * @userdata2[0:31] Current Log Size
+ * @userdata2[32:63] New entry size
+ * @devdesc TPM log buffer add failure.
+ */
+ err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT,
+ RC_TPMLOGMGR_ADDEVENT_FAIL,
+ (NULL == val->newEventPtr ? 0 : 1),
+ (uint64_t)val->logSize << 32 |
+ newLogSize);
+
+ break;
+ }
+
+
+ val->newEventPtr = TCG_PCR_EVENT2_logMarshal(logEvent,
+ val->newEventPtr);
+
+ if (NULL == val->newEventPtr)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM LOG MARSHAL Fail");
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPMLOGMGR_ADDEVENTMARSH_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPMLOGMGR_ADDEVENT
+ * @userdata1 0
+ * @userdata2 0
+ * @devdesc log buffer malloc failure.
+ */
+ err = tpmCreateErrorLog( MOD_TPMLOGMGR_ADDEVENT,
+ RC_TPMLOGMGR_ADDEVENTMARSH_FAIL,
+ 0,
+ 0);
+ break;
+ }
+
+ // Debug display of raw data
+ TRACUCOMP(g_trac_trustedboot, "tpmAddEvent: Start %p",
+ startPtr);
+ TRACUBIN(g_trac_trustedboot, "tpmAddEvent",
+ startPtr, newLogSize);
+
+
+ val->logSize += newLogSize;
+
+
+ } while ( 0 );
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmAddEvent() LS:%d - %s",
+ (int)val->logSize,
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+
+ mutex_unlock( &val->logMutex );
+ return err;
+ }
+
+ uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val)
+ {
+ return val->logSize;
+ }
+
+ void TpmLogMgr_dumpLog(TpmLogMgr* val)
+ {
+
+ // Debug display of raw data
+ TRACUCOMP(g_trac_trustedboot, "tpmDumpLog Size : %d\n",
+ (int)val->logSize);
+ TRACUBIN(g_trac_trustedboot, "tpmDumpLog",
+ val->eventLog, val->logSize);
+ }
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT
+#endif
diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.H b/src/usr/secureboot/trusted/base/tpmLogMgr.H
new file mode 100644
index 000000000..f56e27d7b
--- /dev/null
+++ b/src/usr/secureboot/trusted/base/tpmLogMgr.H
@@ -0,0 +1,130 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/base/tpmLogMgr.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file tpmLogMgr.H
+ *
+ * @brief Trustedboot TPM Event Log Manager
+ *
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+#ifndef __TPMLOGMGR_H
+#define __TPMLOGMGR_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+
+#ifdef __HOSTBOOT_MODULE
+#include <sys/sync.h>
+#include "../trustedboot.H"
+#include "../trustedTypes.H"
+#else
+#include "trustedboot.H"
+#include "trustedTypes.H"
+#endif
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ /// Event log header algorithms
+ struct _TCG_EfiSpecIdEventAlgorithmSize
+ {
+ uint16_t algorithmId;
+ uint16_t digestSize;
+ } PACKED;
+ typedef struct _TCG_EfiSpecIdEventAlgorithmSize
+ TCG_EfiSpecIdEventAlgorithmSize;
+
+ /// Event log header event data
+ struct _TCG_EfiSpecIdEventStruct
+ {
+ char signature[16];
+ uint32_t platformClass;
+ uint8_t specVersionMinor;
+ uint8_t specVersionMajor;
+ uint8_t specErrata;
+ uint8_t uintnSize;
+ uint32_t numberOfAlgorithms;
+ TCG_EfiSpecIdEventAlgorithmSize digestSizes[HASH_COUNT];
+ uint8_t vendorInfoSize;
+ char vendorInfo[0];
+ } PACKED;
+ typedef struct _TCG_EfiSpecIdEventStruct TCG_EfiSpecIdEventStruct;
+ uint32_t TCG_EfiSpecIdEventStruct_size(TCG_EfiSpecIdEventStruct* val);
+
+ enum {
+ TPMLOG_BUFFER_SIZE = 1024, ///< Size of event log buffer in bytes
+ };
+
+ struct _TpmLogMgr
+ {
+ uint32_t logSize; ///< Current byte size of log
+ uint8_t eventLog[TPMLOG_BUFFER_SIZE]; ///< EventLog Buffer
+ uint8_t* newEventPtr; ///< Pointer to location to add new event
+ mutex_t logMutex; ///< Log mutex
+ };
+ typedef struct _TpmLogMgr TpmLogMgr;
+
+ /**
+ * @brief Initialize the log manager
+ * @param[in/out] io_logMgr Return a pointer to the log manager
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t TpmLogMgr_initialize(TpmLogMgr * io_logMgr);
+
+ /**
+ * @brief Add a new event to the log
+ * @param[in] val TpmLogMgr structure
+ * @param[in] logEvent Event log entry to add
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t TpmLogMgr_addEvent(TpmLogMgr* val, TCG_PCR_EVENT2* logEvent);
+
+ /**
+ * @brief Get current log size in bytes
+ * @param[in] val TpmLogMgr structure
+ * @return uint32_t Byte size of log
+ */
+ uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val);
+
+ /**
+ * @brief Dump contents of log to a trace
+ * @param[in] val TpmLogMgr structure
+ */
+ void TpmLogMgr_dumpLog(TpmLogMgr* val);
+
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT namespace
+#endif
+
+#endif
diff --git a/src/usr/secureboot/trusted/base/trustedTypes_base.C b/src/usr/secureboot/trusted/base/trustedTypes_base.C
new file mode 100644
index 000000000..3c3d8d737
--- /dev/null
+++ b/src/usr/secureboot/trusted/base/trustedTypes_base.C
@@ -0,0 +1,261 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/base/trustedTypes_base.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedTypes_base.C
+ *
+ * @brief Trusted boot type inline functions for hostboot base
+ */
+
+/////////////////////////////////////////////////////////////////
+// NOTE: This file is exportable as TSS-Lite for skiboot/PHYP //
+/////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#ifdef __HOSTBOOT_MODULE
+#include "../trustedTypes.H"
+#include "../trustedboot.H"
+#else
+#include "trustedTypes.H"
+#include "trustedboot.H"
+#endif
+
+
+#ifdef __cplusplus
+namespace TRUSTEDBOOT
+{
+#endif
+
+ uint32_t getDigestSize(TPM_Alg_Id i_algId)
+ {
+ uint32_t ret = 0;
+ switch (i_algId)
+ {
+ case TPM_ALG_SHA256:
+ ret = TPM_ALG_SHA256_SIZE;
+ break;
+ default:
+ ret = 0;
+ break;
+ };
+ return ret;
+ }
+
+ uint8_t* TPMT_HA_logMarshal(TPMT_HA* val, uint8_t* i_logBuf)
+ {
+ uint16_t* field16 = (uint16_t*)i_logBuf;
+ *field16 = htole16(val->algorithmId);
+ i_logBuf += sizeof(uint16_t);
+ memcpy(i_logBuf, val->digest.bytes,
+ getDigestSize((TPM_Alg_Id)val->algorithmId));
+ i_logBuf += getDigestSize((TPM_Alg_Id)val->algorithmId);
+ return i_logBuf;
+ }
+
+ size_t TPML_DIGEST_VALUES_marshalSize(TPML_DIGEST_VALUES* val)
+ {
+ size_t ret = sizeof(val->count);
+ for (size_t idx = 0; (idx < val->count && idx < HASH_COUNT); idx++)
+ {
+ ret += TPMT_HA_marshalSize(&(val->digests[idx]));
+ }
+ return ret;
+ }
+
+ uint8_t* TPML_DIGEST_VALUES_logMarshal(TPML_DIGEST_VALUES* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ if (HASH_COUNT < val->count)
+ {
+ i_logBuf = NULL;
+ }
+ else
+ {
+ *field32 = htole32(val->count);
+ i_logBuf += sizeof(uint32_t);
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ i_logBuf = TPMT_HA_logMarshal(&(val->digests[idx]), i_logBuf);
+ if (NULL == i_logBuf) break;
+ }
+ }
+ return i_logBuf;
+ }
+
+ uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val,
+ uint8_t* i_tpmBuf,
+ size_t i_bufSize,
+ bool* o_err)
+ {
+ size_t size = 0;
+ uint32_t* field32;
+
+ *o_err = false;
+ do {
+ // Ensure enough space for unmarshalled data
+ if (sizeof(TCG_PCR_EVENT) > i_bufSize)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ break;
+ }
+
+ // pcrIndex
+ size = sizeof(val->pcrIndex);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->pcrIndex = le32toh(*field32);
+ // Ensure a valid pcr index
+ if (val->pcrIndex >= PCR_MAX)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid pcrIndex %d",
+ val->pcrIndex);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // eventType
+ size = sizeof(val->eventType);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventType = le32toh(*field32);
+ // Ensure a valid event type
+ if (val->eventType == 0 || val->eventType >= EV_INVALID)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventType %d",
+ val->eventType);
+ break;
+ }
+ i_tpmBuf += size;
+
+ // digest
+ size = sizeof(val->digest);
+ memcpy(val->digest, i_tpmBuf, size);
+ i_tpmBuf += size;
+
+ // eventSize
+ size = sizeof(val->eventSize);
+ field32 = (uint32_t*)(i_tpmBuf);
+ val->eventSize = le32toh(*field32);
+ // Ensure a valid eventSize
+ if (val->eventSize >= MAX_TPM_LOG_MSG)
+ {
+ *o_err = true;
+ i_tpmBuf = NULL;
+ TRACFCOMP(g_trac_trustedboot,
+ "ERROR> TCG_PCR_EVENT:logUnmarshal() invalid eventSize %d",
+ val->eventSize);
+ break;
+ }
+ i_tpmBuf += size;
+
+ memcpy(val->event, i_tpmBuf, val->eventSize);
+ i_tpmBuf += val->eventSize;
+
+ } while(0);
+
+ return i_tpmBuf;
+ }
+
+ uint8_t* TCG_PCR_EVENT_logMarshal(TCG_PCR_EVENT* val, uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->pcrIndex);
+ i_logBuf += sizeof(uint32_t);
+
+ field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->eventType);
+ i_logBuf += sizeof(uint32_t);
+
+ memcpy(i_logBuf, val->digest, sizeof(val->digest));
+ i_logBuf += sizeof(val->digest);
+
+ field32 = (uint32_t*)(i_logBuf);
+ *field32 = htole32(val->eventSize);
+ i_logBuf += sizeof(uint32_t);
+
+ if (val->eventSize > 0)
+ {
+ memcpy(i_logBuf, val->event, val->eventSize);
+ i_logBuf += val->eventSize;
+ }
+ return i_logBuf;
+ }
+
+
+ uint8_t* TPM_EVENT_FIELD_logMarshal(TPM_EVENT_FIELD* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ if (MAX_TPM_LOG_MSG < val->eventSize)
+ {
+ i_logBuf = NULL;
+ }
+ else
+ {
+ *field32 = htole32(val->eventSize);
+ i_logBuf += sizeof(uint32_t);
+
+ memcpy(i_logBuf, val->event, val->eventSize);
+ i_logBuf += val->eventSize;
+ }
+ return i_logBuf;
+ }
+
+ size_t TCG_PCR_EVENT2_marshalSize(TCG_PCR_EVENT2* val)
+ {
+ return (sizeof(val->pcrIndex) + sizeof(val->eventType) +
+ TPML_DIGEST_VALUES_marshalSize(&(val->digests)) +
+ TPM_EVENT_FIELD_marshalSize(&(val->event)));
+ }
+
+ uint8_t* TCG_PCR_EVENT2_logMarshal(TCG_PCR_EVENT2* val,
+ uint8_t* i_logBuf)
+ {
+ uint32_t* field32 = (uint32_t*)i_logBuf;
+ *field32 = htole32(val->pcrIndex);
+ i_logBuf += sizeof(uint32_t);
+ field32 = (uint32_t*)i_logBuf;
+ *field32 = htole32(val->eventType);
+ i_logBuf += sizeof(uint32_t);
+
+ i_logBuf = TPML_DIGEST_VALUES_logMarshal(&(val->digests),i_logBuf);
+ if (NULL != i_logBuf)
+ {
+ i_logBuf = TPM_EVENT_FIELD_logMarshal(&(val->event),i_logBuf);
+ }
+ return i_logBuf;
+ }
+
+#ifdef __cplusplus
+} // end TRUSTEDBOOT
+#endif
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 31522ef7f..e9f20db59 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -26,6 +26,7 @@
* @file trustedboot_base.C
*
* @brief Trusted boot base interfaces
+ * This file is compiled in regardless of CONFIG_TPMDD
*/
// ----------------------------------------------
@@ -39,8 +40,11 @@
#include <errl/errludtarget.H>
#include <errl/errludstring.H>
#include <secureboot/trustedbootif.H>
-#include "../trustedboot.H"
#include <secureboot/trustedboot_reasoncodes.H>
+#include "trustedboot_base.H"
+#include "../trustedboot.H"
+#include "../trustedbootUtils.H"
+#include "tpmLogMgr.H"
// ----------------------------------------------
// Trace definitions
@@ -53,6 +57,7 @@ TRAC_INIT( & g_trac_trustedboot, "TRBOOT", KILOBYTE );
namespace TRUSTEDBOOT
{
+#ifdef CONFIG_TPMDD
/// Global object to store TPM status
SystemTpms systemTpms;
@@ -65,7 +70,10 @@ TpmTarget::TpmTarget()
memset(this, 0, sizeof(TpmTarget));
available = true; // Default to available until we know better
mutex_init(&tpmMutex);
+
}
+#endif
+
errlHndl_t pcrExtend(TPM_Pcr i_pcr,
uint8_t* i_digest,
@@ -74,10 +82,206 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
{
errlHndl_t err = NULL;
#ifdef CONFIG_TPMDD
- /// @todo RTC:125288 Add call to extend the PCR
+ TPM_Alg_Id algId = TPM_ALG_SHA256;
+
+ size_t fullDigestSize = getDigestSize(algId);
+ char logMsg[MAX_TPM_LOG_MSG];
+
+ TRACDCOMP( g_trac_trustedboot,
+ ENTER_MRK"pcrExtend()" );
+ TRACUCOMP( g_trac_trustedboot,
+ ENTER_MRK"pcrExtend() pcr=%d msg='%s' digest=%016llX",
+ i_pcr,
+ i_logMsg,
+ *(reinterpret_cast<uint64_t*>(i_digest)));
+
+ // Ensure proper digest size
+ uint8_t digestData[fullDigestSize];
+ memset(digestData, 0, sizeof(digestData));
+
+ // copy over the incoming digest to append or truncate to what we need
+ memcpy(digestData, i_digest,
+ (i_digestSize < fullDigestSize ? i_digestSize : fullDigestSize));
+
+ // Truncate logMsg if required
+ memset(logMsg, 0, sizeof(logMsg));
+ memcpy(logMsg, i_logMsg,
+ (strlen(i_logMsg) < MAX_TPM_LOG_MSG ? strlen(i_logMsg) :
+ MAX_TPM_LOG_MSG));
+
+ for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx++)
+ {
+ // Add the event to this TPM, if an error occurs the TPM will
+ // be marked as failed and the error log committed
+ pcrExtendSingleTpm(systemTpms.tpm[idx],
+ i_pcr,
+ algId,
+ digestData,
+ fullDigestSize,
+ logMsg);
+ }
+
+
+ // Lastly make sure we are in a state where we have a functional TPM
+ err = tpmVerifyFunctionalTpmExists();
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ EXIT_MRK"pcrExtend() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
#endif
return err;
}
+#ifdef CONFIG_TPMDD
+void pcrExtendSingleTpm(TpmTarget & io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* i_digest,
+ size_t i_digestSize,
+ const char* i_logMsg)
+{
+ errlHndl_t err = NULL;
+ TCG_PCR_EVENT2 eventLog;
+ bool unlock = false;
+
+ do
+ {
+
+ mutex_lock( &io_target.tpmMutex );
+ unlock = true;
+
+ // Allocate the TPM log if it hasn't been already
+ if (!io_target.failed &&
+ io_target.available &&
+ NULL == io_target.logMgr)
+ {
+ io_target.logMgr = new TpmLogMgr;
+ err = TpmLogMgr_initialize(io_target.logMgr);
+ if (NULL != err)
+ {
+ break;
+ }
+ }
+
+
+
+ // If the TPM init has occurred and it is currently
+ // functional we will do our extension
+ if (io_target.available &&
+ io_target.initAttempted &&
+ !io_target.failed)
+ {
+
+ /// @todo RTC:125288 Add call to extend the PCR
+ }
+
+ // Now we log the event, we will do this in two scenarios
+ // - !initAttempted - prior to IPL of the TPM we log for replay
+ // - initAttempted && !failed - TPM is functional so we log
+ if ((io_target.available &&
+ !io_target.initAttempted) ||
+ (io_target.available &&
+ io_target.initAttempted &&
+ !io_target.failed))
+ {
+ memset(&eventLog, 0, sizeof(eventLog));
+ eventLog.pcrIndex = i_pcr;
+ eventLog.eventType = EV_ACTION;
+
+ // Update digest information, we only use 1 entry
+ eventLog.digests.count = 1;
+ eventLog.digests.digests[0].algorithmId = i_algId;
+ memcpy(eventLog.digests.digests[0].digest.bytes,
+ i_digest, i_digestSize);
+
+ // Event field data
+ eventLog.event.eventSize = strlen(i_logMsg);
+ assert(eventLog.event.eventSize <= MAX_TPM_LOG_MSG,
+ "TPM Log message too long");
+ memcpy(eventLog.event.event, i_logMsg, strlen(i_logMsg));
+
+ err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog);
+ if (NULL != err)
+ {
+ break;
+ }
+ }
+
+ } while ( 0 );
+
+ if (NULL != err)
+ {
+ // We failed to extend to this TPM we can no longer use it
+ tpmMarkFailed(&io_target);
+
+ // Log this failure
+ errlCommit(err, SECURE_COMP_ID);
+ err = NULL;
+ }
+
+ if (unlock)
+ {
+ mutex_unlock(&io_target.tpmMutex);
+ }
+ return;
+}
+
+void tpmMarkFailed(TpmTarget * io_target)
+{
+
+ TRACFCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmMarkFailed() Marking TPM as failed : "
+ "tgt=0x%X chip=%d",
+ TARGETING::get_huid(io_target->nodeTarget),
+ io_target->chip);
+
+ io_target->failed = true;
+ /// @todo RTC:125287 Add fail marker to TPM log and disable TPM access
+
+}
+
+errlHndl_t tpmVerifyFunctionalTpmExists()
+{
+ errlHndl_t err = NULL;
+ bool foundFunctional = false;
+
+ for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++)
+ {
+ if (!systemTpms.tpm[idx].failed ||
+ !systemTpms.tpm[idx].initAttempted)
+ {
+ foundFunctional = true;
+ break;
+ }
+ }
+
+ if (!foundFunctional)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "NO FUNCTIONAL TPM FOUND");
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_NOFUNCTIONALTPM_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_VERIFYFUNCTIONAL
+ * @userdata1 0
+ * @userdata2 0
+ * @devdesc No functional TPMs exist in the system
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_VERIFYFUNCTIONAL,
+ RC_TPM_NOFUNCTIONALTPM_FAIL,
+ 0, 0,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ }
+
+ return err;
+}
+#endif
+
} // end TRUSTEDBOOT
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.H b/src/usr/secureboot/trusted/base/trustedboot_base.H
new file mode 100644
index 000000000..70d160b02
--- /dev/null
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.H
@@ -0,0 +1,67 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/base/trustedboot_base.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file trustedboot_base.H
+ *
+ * @brief Trustedboot TPM interfaces in HB base
+ *
+ */
+#ifndef __TRUSTEDBOOT_BASE_H
+#define __TRUSTEDBOOT_BASE_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#include <secureboot/trustedbootif.H>
+#include "../trustedTypes.H"
+
+namespace TRUSTEDBOOT
+{
+
+
+/**
+ * @brief Verify a functional TPM still exists in the system
+ * @return errlHndl_t NULL if TPM available, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t tpmVerifyFunctionalTpmExists();
+
+/**
+ * @brief Extend a measurement into a TPM and log
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in] i_pcr PCR to write to
+ * @param[in] i_digest Digest value to write to PCR
+ * @param[in] i_digestSize Byte size of i_digest data
+ * @param[in] i_logMsg Null terminated log message
+ */
+void pcrExtendSingleTpm(TpmTarget & io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* i_digest,
+ size_t i_digestSize,
+ const char* i_logMsg);
+
+
+} // end TRUSTEDBOOT namespace
+#endif
OpenPOWER on IntegriCloud