diff options
| author | Chris Engel <cjengel@us.ibm.com> | 2016-02-19 10:19:17 -0600 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-05-11 17:13:59 -0400 |
| commit | 2846d635adc08c844d68d68f7a7e2ff885c4fad5 (patch) | |
| tree | 326a64051d3868799c74df55affc252a6a9861f9 /src/usr/secureboot/trusted/base | |
| parent | 483342c80d5431cd5866ee64464d62b32bf33b56 (diff) | |
| download | talos-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.C | 87 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/tpmLogMgr.H | 45 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedTypes_base.C | 257 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 41 |
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 |

