summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted/base
diff options
context:
space:
mode:
authorChris Engel <cjengel@us.ibm.com>2016-02-19 10:19:17 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-05-11 17:13:59 -0400
commit2846d635adc08c844d68d68f7a7e2ff885c4fad5 (patch)
tree326a64051d3868799c74df55affc252a6a9861f9 /src/usr/secureboot/trusted/base
parent483342c80d5431cd5866ee64464d62b32bf33b56 (diff)
downloadtalos-hostboot-2846d635adc08c844d68d68f7a7e2ff885c4fad5.tar.gz
talos-hostboot-2846d635adc08c844d68d68f7a7e2ff885c4fad5.zip
Send hash of pnor sections to TPM
Replay log events to TPM after initialization Change-Id: Ibab5e28790324c28a7cd9fb2805041d7a896376a RTC:125290 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23898 Tested-by: Jenkins Server Reviewed-by: Timothy R. Block <block@us.ibm.com> Tested-by: FSP CI Jenkins Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot/trusted/base')
-rw-r--r--src/usr/secureboot/trusted/base/tpmLogMgr.C87
-rw-r--r--src/usr/secureboot/trusted/base/tpmLogMgr.H45
-rw-r--r--src/usr/secureboot/trusted/base/trustedTypes_base.C257
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C41
4 files changed, 394 insertions, 36 deletions
diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.C b/src/usr/secureboot/trusted/base/tpmLogMgr.C
index 903a2f3ba..d863afc3e 100644
--- a/src/usr/secureboot/trusted/base/tpmLogMgr.C
+++ b/src/usr/secureboot/trusted/base/tpmLogMgr.C
@@ -94,7 +94,6 @@ namespace TRUSTEDBOOT
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);
@@ -120,14 +119,12 @@ namespace TRUSTEDBOOT
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
@@ -139,7 +136,6 @@ namespace TRUSTEDBOOT
val->logSize,
((TB_SUCCESS == err) ? "No Error" : "With Error") );
}
-
return err;
}
@@ -241,6 +237,89 @@ namespace TRUSTEDBOOT
val->eventLog, val->logSize);
}
+
+ const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val)
+ {
+ TCG_PCR_EVENT event;
+ bool err = false;
+ const uint8_t* result = NULL;
+
+ // Header event in the log is always first, we skip over that
+ const uint8_t* firstEvent = val->eventLog;
+ memset(&event, 0, sizeof(TCG_PCR_EVENT));
+
+ firstEvent = TCG_PCR_EVENT_logUnmarshal(&event, firstEvent,
+ sizeof(TCG_PCR_EVENT),
+ &err);
+ if (NULL != firstEvent && !err &&
+ firstEvent < val->newEventPtr)
+ {
+ result = firstEvent;
+ }
+
+ return result;
+ }
+
+ const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val,
+ const uint8_t* i_handle,
+ TCG_PCR_EVENT2* i_eventLog,
+ bool* o_err)
+ {
+ const uint8_t* l_resultPtr = NULL;
+ if (NULL == i_handle)
+ {
+ *o_err = true;
+ }
+ else
+ {
+ memset(i_eventLog, 0, sizeof(TCG_PCR_EVENT2));
+ TRACUCOMP( g_trac_trustedboot, "TPM getNextEvent 0x%p", i_handle);
+ l_resultPtr = TCG_PCR_EVENT2_logUnmarshal(i_eventLog, i_handle,
+ sizeof(TCG_PCR_EVENT2),
+ o_err);
+ if (NULL == l_resultPtr)
+ {
+ // An error was detected, ensure o_err is set
+ *o_err = true;
+ }
+ else if (l_resultPtr >= val->newEventPtr)
+ {
+ l_resultPtr = NULL;
+ }
+ }
+
+ return l_resultPtr;
+ }
+
+ TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ const uint8_t* i_digest,
+ size_t i_digestSize,
+ const char* i_logMsg)
+ {
+ TCG_PCR_EVENT2 eventLog;
+
+ memset(&eventLog, 0, sizeof(eventLog));
+ eventLog.pcrIndex = i_pcr;
+ eventLog.eventType = EV_ACTION;
+
+ // Update digest information, we only use 1 entry
+ eventLog.digests.count = 1;
+ eventLog.digests.digests[0].algorithmId = i_algId;
+ memcpy(eventLog.digests.digests[0].digest.bytes,
+ i_digest,
+ (i_digestSize > sizeof(TPMU_HA) ?
+ sizeof(TPMU_HA) : i_digestSize));
+
+ // Event field data
+ eventLog.event.eventSize = strlen(i_logMsg);
+ memcpy(eventLog.event.event, i_logMsg,
+ (strlen(i_logMsg) > MAX_TPM_LOG_MSG ?
+ MAX_TPM_LOG_MSG : strlen(i_logMsg)) );
+
+ return eventLog;
+ }
+
#ifdef __cplusplus
} // end TRUSTEDBOOT
#endif
diff --git a/src/usr/secureboot/trusted/base/tpmLogMgr.H b/src/usr/secureboot/trusted/base/tpmLogMgr.H
index f56e27d7b..69909a925 100644
--- a/src/usr/secureboot/trusted/base/tpmLogMgr.H
+++ b/src/usr/secureboot/trusted/base/tpmLogMgr.H
@@ -116,6 +116,51 @@ namespace TRUSTEDBOOT
*/
uint32_t TpmLogMgr_getLogSize(TpmLogMgr* val);
+
+ /**
+ * @brief Get pointer to first event in eventLog past the header event
+ * @param[in] val TpmLogMgr structure
+ * @return uint8_t First event handle
+ * @retval NULL On empty log
+ * @retval !NULL First event handle
+ */
+ const uint8_t* TpmLogMgr_getFirstEvent(TpmLogMgr* val);
+
+ /**
+ * @brief Get pointer to next event in log and unmarshal log contents
+ * into i_eventLog
+ *
+ * @param[in] i_handle Current event to unmarshal
+ * @param[in] i_eventLog EVENT2 structure to populate
+ * @param[in] o_err Indicates if an error occurred during
+ * LogUnmarshal.
+ *
+ * @return uint8_t* Pointer to the next event after i_handle
+ * @retval NULL When val contains last entry in log
+ * @retval !NULL When addition log entries available
+ */
+ const uint8_t* TpmLogMgr_getNextEvent(TpmLogMgr* val,
+ const uint8_t* i_handle,
+ TCG_PCR_EVENT2* i_eventLog,
+ bool* o_err);
+
+ /**
+ * @brief Get a TCG_PCR_EVENT2 populated with required data
+ *
+ * @param[in] i_pcr PCR to write to
+ * @param[in] i_algId Algorithm to use
+ * @param[in] i_digest Digest value to write to PCR
+ * @param[in] i_digestSize Byte size of i_digest array
+ * @param[in] i_logMsg Null terminated Log message
+ *
+ * @return TCG_PCR_EVENT2 PCR event log
+ */
+ TCG_PCR_EVENT2 TpmLogMgr_genLogEventPcrExtend(TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ const uint8_t* i_digest,
+ size_t i_digestSize,
+ const char* i_logMsg);
+
/**
* @brief Dump contents of log to a trace
* @param[in] val TpmLogMgr structure
diff --git a/src/usr/secureboot/trusted/base/trustedTypes_base.C b/src/usr/secureboot/trusted/base/trustedTypes_base.C
index bff23a911..5ce0614f3 100644
--- a/src/usr/secureboot/trusted/base/trustedTypes_base.C
+++ b/src/usr/secureboot/trusted/base/trustedTypes_base.C
@@ -65,7 +65,7 @@ namespace TRUSTEDBOOT
return ret;
}
- uint8_t* TPMT_HA_logMarshal(TPMT_HA* val, uint8_t* i_logBuf)
+ uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf)
{
uint16_t* field16 = (uint16_t*)i_logBuf;
*field16 = htole16(val->algorithmId);
@@ -76,7 +76,64 @@ namespace TRUSTEDBOOT
return i_logBuf;
}
- size_t TPML_DIGEST_VALUES_marshalSize(TPML_DIGEST_VALUES* val)
+ const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val,
+ const uint8_t* i_tpmBuf, bool* o_err)
+ {
+ do {
+ *o_err = false;
+
+ // algorithmId
+ size_t size = sizeof(val->algorithmId);
+ uint16_t* 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++)
@@ -86,7 +143,7 @@ namespace TRUSTEDBOOT
return ret;
}
- uint8_t* TPML_DIGEST_VALUES_logMarshal(TPML_DIGEST_VALUES* val,
+ uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val,
uint8_t* i_logBuf)
{
uint32_t* field32 = (uint32_t*)i_logBuf;
@@ -107,10 +164,63 @@ namespace TRUSTEDBOOT
return i_logBuf;
}
- uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val,
- uint8_t* i_tpmBuf,
- size_t i_bufSize,
- bool* o_err)
+ const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err)
+ {
+ do {
+ *o_err = false;
+
+ // count
+ size_t size = sizeof(val->count);
+ uint32_t* 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;
@@ -186,7 +296,8 @@ namespace TRUSTEDBOOT
return i_tpmBuf;
}
- uint8_t* TCG_PCR_EVENT_logMarshal(TCG_PCR_EVENT* val, uint8_t* i_logBuf)
+ 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);
@@ -211,8 +322,12 @@ namespace TRUSTEDBOOT
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(TPM_EVENT_FIELD* val,
+ uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val,
uint8_t* i_logBuf)
{
uint32_t* field32 = (uint32_t*)i_logBuf;
@@ -231,14 +346,56 @@ namespace TRUSTEDBOOT
return i_logBuf;
}
- size_t TCG_PCR_EVENT2_marshalSize(TCG_PCR_EVENT2* val)
+ const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val,
+ const uint8_t* i_tpmBuf,
+ bool* o_err)
+ {
+ do {
+ *o_err = false;
+
+ // Event size
+ size_t size = sizeof(val->eventSize);
+ uint32_t* 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(TCG_PCR_EVENT2* val,
+ uint8_t* TCG_PCR_EVENT2_logMarshal(const TCG_PCR_EVENT2* val,
uint8_t* i_logBuf)
{
uint32_t* field32 = (uint32_t*)i_logBuf;
@@ -256,6 +413,84 @@ namespace TRUSTEDBOOT
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 >= 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/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index dcd5a3191..ea17bc39b 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -88,8 +88,7 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
size_t fullDigestSize = getDigestSize(algId);
char logMsg[MAX_TPM_LOG_MSG];
- TRACDCOMP( g_trac_trustedboot,
- ENTER_MRK"pcrExtend()" );
+ TRACDCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend()" );
TRACUCOMP( g_trac_trustedboot,
ENTER_MRK"pcrExtend() pcr=%d msg='%s' digest=%016llX",
i_pcr,
@@ -122,7 +121,6 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
logMsg);
}
-
// Lastly make sure we are in a state where we have a functional TPM
err = tpmVerifyFunctionalTpmExists();
@@ -149,7 +147,6 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
do
{
-
mutex_lock( &io_target.tpmMutex );
unlock = true;
@@ -175,22 +172,9 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
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));
-
+ // 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)
{
@@ -215,7 +199,6 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
break;
}
}
-
} while ( 0 );
if (NULL != err)
@@ -289,6 +272,22 @@ errlHndl_t tpmVerifyFunctionalTpmExists()
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;
+}
+
#endif
} // end TRUSTEDBOOT
OpenPOWER on IntegriCloud