From 2846d635adc08c844d68d68f7a7e2ff885c4fad5 Mon Sep 17 00:00:00 2001 From: Chris Engel Date: Fri, 19 Feb 2016 10:19:17 -0600 Subject: 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 Tested-by: FSP CI Jenkins Reviewed-by: Stephen M. Cprek Reviewed-by: Daniel M. Crowell --- src/include/usr/secureboot/secure_reasoncodes.H | 4 +- .../usr/secureboot/trustedboot_reasoncodes.H | 1 + src/usr/pnor/pnor_common.C | 52 ++++- src/usr/pnor/pnor_common.H | 13 ++ src/usr/secureboot/base/securerom.C | 40 +++- src/usr/secureboot/base/securerom.H | 16 +- src/usr/secureboot/trusted/base/tpmLogMgr.C | 87 ++++++- src/usr/secureboot/trusted/base/tpmLogMgr.H | 45 ++++ .../secureboot/trusted/base/trustedTypes_base.C | 257 ++++++++++++++++++++- src/usr/secureboot/trusted/base/trustedboot_base.C | 41 ++-- src/usr/secureboot/trusted/test/tpmLogMgrTest.H | 227 +++++++++++++++--- src/usr/secureboot/trusted/trustedTypes.C | 98 ++++---- src/usr/secureboot/trusted/trustedTypes.H | 114 +++++---- src/usr/secureboot/trusted/trustedboot.C | 84 ++++++- src/usr/secureboot/trusted/trustedbootCmds.C | 2 +- src/usr/secureboot/trusted/trustedbootUtils.C | 16 -- 16 files changed, 890 insertions(+), 207 deletions(-) (limited to 'src') diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H index 959278710..404575fcd 100644 --- a/src/include/usr/secureboot/secure_reasoncodes.H +++ b/src/include/usr/secureboot/secure_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -36,6 +36,7 @@ namespace SECUREBOOT MOD_SECURE_ROM_INIT = 0x02, MOD_SECURE_ROM_VERIFY = 0x03, MOD_SECURE_ROM_CLEANUP = 0x04, + MOD_SECURE_ROM_SHA512 = 0x05, }; enum SECUREReasonCode @@ -47,6 +48,7 @@ namespace SECUREBOOT RC_SET_PERMISSION_FAIL_EXE = SECURE_COMP_ID | 0x05, RC_SET_PERMISSION_FAIL_WRITE = SECURE_COMP_ID | 0x06, RC_ROM_VERIFY = SECURE_COMP_ID | 0x07, + RC_ROM_SHA512 = SECURE_COMP_ID | 0x08, // Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H }; diff --git a/src/include/usr/secureboot/trustedboot_reasoncodes.H b/src/include/usr/secureboot/trustedboot_reasoncodes.H index 9f3ad03c5..cff1bba32 100644 --- a/src/include/usr/secureboot/trustedboot_reasoncodes.H +++ b/src/include/usr/secureboot/trustedboot_reasoncodes.H @@ -52,6 +52,7 @@ namespace TRUSTEDBOOT MOD_TPM_VERIFYFUNCTIONAL = 0x06, MOD_TPM_CMD_PCREXTEND = 0x07, MOD_TPM_CMD_PCRREAD = 0x08, + MOD_TPM_REPLAY_LOG = 0x09, MOD_TPMLOGMGR_INITIALIZE = 0x10, MOD_TPMLOGMGR_ADDEVENT = 0x11, diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C index d4dd7f498..22841b20c 100644 --- a/src/usr/pnor/pnor_common.C +++ b/src/usr/pnor/pnor_common.C @@ -34,6 +34,8 @@ #include #include #include // @FIXME RTC 132398 +#include +#include // Trace definition trace_desc_t* g_trac_pnor = NULL; @@ -288,11 +290,26 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC) } - // TODO RTC:96009 handle version header w/secureboot if (o_TOC[l_secId].version == FFS_VERS_SHA512) { TRACFCOMP(g_trac_pnor, "PNOR::parseTOC: Incrementing" " Flash Address for SHA Header"); + uint32_t l_addr = o_TOC[l_secId].flashAddr; + size_t l_headerSize = 0; + if (o_TOC[l_secId].integrity == FFS_INTEG_ECC_PROTECT) + { + l_headerSize = PAGESIZE_PLUS_ECC; + } + else + { + l_headerSize = PAGESIZE; + } + l_errhdl = PNOR::extendHash(l_addr, l_headerSize, + cv_EYECATCHER[l_secId]); + if (l_errhdl) + { + break; + } } } for(int tmpId = 0; @@ -309,3 +326,36 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC) TRACUCOMP(g_trac_pnor, "< PNOR::parseTOC" ); return l_errhdl; } + +errlHndl_t PNOR::extendHash(uint64_t i_addr, size_t i_size, const char* i_name) +{ + errlHndl_t l_errhdl = NULL; + + do { + #ifndef __HOSTBOOT_RUNTIME + // Read data from the PNOR DD + uint8_t* l_buf = new uint8_t[i_size](); + TARGETING::Target* l_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + l_errhdl = DeviceFW::deviceRead(l_target, l_buf, i_size, + DEVICE_PNOR_ADDRESS(0,i_addr)); + if (l_errhdl) + { + break; + } + + SHA512_t l_hash = {0}; + SECUREBOOT::hashBlob(l_buf, i_size, l_hash); + l_errhdl = TRUSTEDBOOT::pcrExtend(TRUSTEDBOOT::PCR_0, l_hash, + sizeof(SHA512_t), i_name); + delete[] l_buf; + + if (l_errhdl) + { + break; + } + #endif + } while(0); + + return l_errhdl; +} + diff --git a/src/usr/pnor/pnor_common.H b/src/usr/pnor/pnor_common.H index 3bf6022d7..e8b6bd4f8 100644 --- a/src/usr/pnor/pnor_common.H +++ b/src/usr/pnor/pnor_common.H @@ -28,6 +28,7 @@ #include #include "pnor_utils.H" #include "ffs.h" +#include /************************************************************ * Provides common functions for Hostboot IPL and runtime @@ -72,6 +73,18 @@ namespace PNOR { void physicalToMmioOffset(uint64_t i_hbbAddress, uint64_t& o_mmioOffset); + /** + * @brief Reads version header of section, hashes it, and extends to tpm + * buffer list. + * + * @parm i_addr Offset into flash to read + * @parm i_size Number of bytes to read + * @parm i_name Name of PNOR section + * + * @return Error from operation + */ + errlHndl_t extendHash(uint64_t i_addr, size_t i_size, const char* i_name); + } #endif diff --git a/src/usr/secureboot/base/securerom.C b/src/usr/secureboot/base/securerom.C index 28bb22983..4174bf6a6 100644 --- a/src/usr/secureboot/base/securerom.C +++ b/src/usr/secureboot/base/securerom.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2015 */ +/* Contributors Listed Below - COPYRIGHT 2013,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -78,9 +78,9 @@ errlHndl_t verifyContainer(void * i_container, size_t i_size) * @brief Hash Signed Blob * */ -errlHndl_t hashBlob(void * i_blob, size_t i_size) +errlHndl_t hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf) { - return Singleton::instance().hashBlob(i_blob, i_size); + return Singleton::instance().hashBlob(i_blob, i_size, io_buf); } @@ -391,21 +391,43 @@ errlHndl_t SecureROM::verifyContainer(void * i_container, size_t i_size) /** * @brief Hash Blob */ -errlHndl_t SecureROM::hashBlob(void * i_blob, size_t i_size) +errlHndl_t SecureROM::hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf) { TRACDCOMP(g_trac_secure,INFO_MRK"SecureROM::hashBlob() NOT " "supported, but not returning error log"); - // @todo RTC:34080 - Add support for this function - errlHndl_t l_errl = NULL; - TRACDCOMP(g_trac_secure,EXIT_MRK"SecureROM::hashBlob() - %s", - ((NULL == l_errl) ? "No Error" : "With Error") ); + do{ +#ifdef CONFIG_ROM_CODE_PRESENT - return l_errl; + // Check to see if ROM has already been initialized + // This should have been done early in IPL so assert if this + // is not the case as system is in a bad state + assert(iv_device_ptr != NULL); + + // Set startAddr to ROM_SHA512() function at an offset of Secure ROM + uint64_t l_rom_SHA512_startAddr = reinterpret_cast( + iv_device_ptr) + + SHA512_HASH_FUNCTION_OFFSET; + + call_rom_SHA512(reinterpret_cast(l_rom_SHA512_startAddr), + reinterpret_cast(i_blob), + i_size, + reinterpret_cast(io_buf)); + TRACUCOMP(g_trac_secure,"SecureROM::hashBlob(): " + "call_rom_SHA512: blob=%p size=0x%X addr=%p (iv_d_p=%p)", + i_blob, i_size, l_rom_SHA512_startAddr, + iv_device_ptr); +#endif + }while(0); + + + TRACDCOMP(g_trac_secure,EXIT_MRK"SecureROM::hashBlob()"); + + return l_errl; } diff --git a/src/usr/secureboot/base/securerom.H b/src/usr/secureboot/base/securerom.H index e4472c895..ad12a5a8a 100644 --- a/src/usr/secureboot/base/securerom.H +++ b/src/usr/secureboot/base/securerom.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,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. */ @@ -56,7 +58,8 @@ typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ \ typedef uint8_t sha2_byte; /* Exactly 1 byte */ -void SHA512_Hash(const sha2_byte *data, size_t len, sha2_hash_t *result); +// This is the interface that call_rom_SHA512 calls into +// void SHA512_Hash(const sha2_byte *data, size_t len, sha2_hash_t *result); /* From ROM.h */ @@ -145,13 +148,14 @@ class SecureROM /** * @brief Hash Blob * - * @param[in] i_blob Void pointer to effective address - * of blob - * @param[in] i_size Size of blob in bytes + * @param[in] i_blob Void pointer to effective address + * of blob + * @param[in] i_size Size of blob in bytes + * @param[in/out] io_buf Resulting hash buffer * * @return errlHndl_t NULL on success */ - errlHndl_t hashBlob(void * i_blob, size_t i_size); + errlHndl_t hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf); protected: 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 diff --git a/src/usr/secureboot/trusted/test/tpmLogMgrTest.H b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H index dd30cf682..537ada4b0 100755 --- a/src/usr/secureboot/trusted/test/tpmLogMgrTest.H +++ b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H @@ -46,6 +46,35 @@ class TPMLogMgrTest: public CxxTest::TestSuite { public: + /** + * @brief Retrieve a Tpm log manager to test with + */ + void getTestLogMgr(TpmLogMgr* logMgr) + { + + errlHndl_t err = TpmLogMgr_initialize(logMgr); + if( NULL != err ) + { + TS_FAIL( "getTestLogMgr - Error detected" ); + errlCommit( err, SECURE_COMP_ID ); + delete err; + err = NULL; + } + else if (TpmLogMgr_getLogSize(logMgr) != 69) + // 69 is size of header entry + { + TS_FAIL( "getTestLogMgr - Failed to find " + "proper header log Len=%d", + TpmLogMgr_getLogSize(logMgr)); + } + else + { + TRACUCOMP(g_trac_trustedboot, "getTestLogMgr - " + "Allocate returned as expected. Len=%d", + TpmLogMgr_getLogSize(logMgr)); + } + } + /** * @brief TPM Log Allocate Test */ @@ -61,38 +90,10 @@ class TPMLogMgrTest: public CxxTest::TestSuite do { - + // Initialize logMgr TpmLogMgr logMgr; + getTestLogMgr(&logMgr); - num_ops++; - err = TpmLogMgr_initialize(&logMgr); - - if( NULL != err ) - { - fails++; - TS_FAIL( "testTPMLogMgrAllocate - Error detected" ); - errlCommit( err, - SECURE_COMP_ID ); - delete err; - err = NULL; - break; - } - else if (TpmLogMgr_getLogSize(&logMgr) != 69) - // 69 is size of header entry - { - fails++; - TS_FAIL( "testTPMLogMgrAllocate - Failed to find " - "proper header log Len=%d", - TpmLogMgr_getLogSize(&logMgr)); - break; - - } - else - { - TRACUCOMP(g_trac_trustedboot, "testTPMLogMgrAllocate - " - "Allocate returned as expected. Len=%d", - TpmLogMgr_getLogSize(&logMgr)); - } // Bump full size by the header totalLogSize = TpmLogMgr_getLogSize(&logMgr); @@ -184,7 +185,6 @@ class TPMLogMgrTest: public CxxTest::TestSuite } // End for - // Lastly dump the log to a trace so we can review it TpmLogMgr_dumpLog(&logMgr); @@ -194,7 +194,172 @@ class TPMLogMgrTest: public CxxTest::TestSuite fails, num_ops ); } + /** + * @brief Add generic test event to log and return the event added + */ + TCG_PCR_EVENT2 addTestLogEvent(TpmLogMgr& i_logMgr, + const char* i_logMsg) + { + // Set components of TCG_PCR_EVENT2 + TPM_Pcr pcr = PCR_0; + TPM_Alg_Id algId = TPM_ALG_SHA256; + size_t digestSize = TPM_ALG_SHA256_SIZE; + uint8_t digest[digestSize]; + for (size_t idx = 0; idx < digestSize; idx++) + { + digest[idx] = idx+1; + } + + // Get a TCG_PCR_EVENT2 + TCG_PCR_EVENT2 eventLog = TpmLogMgr_genLogEventPcrExtend( + pcr, algId, + digest, digestSize, i_logMsg); + + // Add event to log + errlHndl_t err = TpmLogMgr_addEvent(&i_logMgr, &eventLog); + if (err) + { + TS_FAIL("addTestLogEvent - Failed to addEvent with message = %s", + i_logMsg); + errlCommit( err, SECURE_COMP_ID ); + delete err; + err = NULL; + } + + return eventLog; + } + + /** + * @brief TPM Log read single entry test + */ + void testTpmLogReadSingleEntry ( void ) + { + TRACFCOMP( g_trac_trustedboot, "testTpmLogReadSingleEntry - Start" ); + + do { + // Initialize logMgr + TpmLogMgr logMgr; + getTestLogMgr(&logMgr); + + // Add event to log + const char* logMsg = "testTpmLogReadSingleEntry"; + TCG_PCR_EVENT2 eventLog = addTestLogEvent(logMgr, logMsg); + + // Retrive event from log + TCG_PCR_EVENT2 resultEventLog; + const uint8_t* eventHndl = TpmLogMgr_getFirstEvent(&logMgr); + if (eventHndl == NULL) + { + TS_FAIL( "testTpmLogReadSingleEntry - Log only contains header event" ); + break; + } + bool unMarshalError = false; + eventHndl = TpmLogMgr_getNextEvent(&logMgr, eventHndl, + &resultEventLog, + &unMarshalError); + if (unMarshalError) + { + TS_FAIL( "testTpmLogReadSingleEntry - LogUnmarshall failed"); + break; + } + // Ensure getNextEvent returned NULL as there is only one entry + if (eventHndl != NULL) + { + TS_FAIL( "testTpmLogReadSingleEntry - Unexpected entries in eventLog"); + break; + } + + // Ensure == operator is correct + if (memcmp(&eventLog, &resultEventLog, sizeof(TCG_PCR_EVENT2)) + != 0) + { + TS_FAIL( "testTpmLogReadSingleEntry - ==operator failed to compare events"); + break; + } + + // Ensure what we read out matches what we put in + if ( eventLog == resultEventLog ) + { + TRACFCOMP( g_trac_trustedboot, "testTpmLogReadSingleEntry - Success read Event"); + } + else + { + TS_FAIL( "testTpmLogReadSingleEntry - Failed to read Event"); + break; + } + + } while(0); + + TRACFCOMP( g_trac_trustedboot, "testTpmLogReadSingleEntry - End" ); + } + + /** + * @brief TPM Log read empty log + */ + void testTpmLogReadEmptyLog ( void ) + { + TRACFCOMP( g_trac_trustedboot, "testTpmLogReadEmptyLog - Start" ); + + do { + // Initialize logMgr + TpmLogMgr logMgr; + getTestLogMgr(&logMgr); + + // Ensure there is only a header event in the log + if (TpmLogMgr_getFirstEvent(&logMgr) != NULL) + { + TS_FAIL( "testTpmLogReadEmptyLog - Read past actual eventLog"); + break; + } + } + while (0); + } + + /** + * @brief TPM Log read past valid log test + */ + void testTpmLogReadPastValidLog ( void ) + { + TRACFCOMP( g_trac_trustedboot, "testTpmLogReadPastValidLog - Start" ); + + do { + // Initialize logMgr + TpmLogMgr logMgr; + getTestLogMgr(&logMgr); + + // Add event to log + const char* logMsg = "testTpmLogReadPastValidLog"; + addTestLogEvent(logMgr, logMsg); + // Retrive event from log + TCG_PCR_EVENT2 resultEventLog; + const uint8_t* eventHndl = TpmLogMgr_getFirstEvent(&logMgr); + if (eventHndl == NULL) + { + TS_FAIL( "testTpmLogReadPastValidLog - Log only contains header event" ); + break; + } + + // Try reading past a valid log + bool unMarshalError = false; + for (int i = 0; i < 2; ++i) + { + eventHndl = TpmLogMgr_getNextEvent(&logMgr, eventHndl, + &resultEventLog, + &unMarshalError); + if (i == 0 && unMarshalError) + { + TS_FAIL( "testTpmLogReadPastValidLog - LogUnmarshall failed"); + break; + } + if (i == 1 && (eventHndl != NULL || !unMarshalError ) ) + { + TS_FAIL( "testTpmLogReadPastValidLog - Read past actual eventLog without posting error and returning NULL"); + } + } + } + while (0); + } }; #endif diff --git a/src/usr/secureboot/trusted/trustedTypes.C b/src/usr/secureboot/trusted/trustedTypes.C index 331031ade..48b069a3b 100644 --- a/src/usr/secureboot/trusted/trustedTypes.C +++ b/src/usr/secureboot/trusted/trustedTypes.C @@ -44,7 +44,7 @@ namespace TRUSTEDBOOT { #endif - uint8_t* unmarshalChunk(uint8_t* i_tpmBuf, + const uint8_t* unmarshalChunk(const uint8_t* i_tpmBuf, size_t * io_tpmBufSize, void* o_chunkPtr, size_t i_chunkSize); @@ -52,10 +52,10 @@ namespace TRUSTEDBOOT uint8_t* marshalChunk(uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize, - void* i_chunkPtr, + const void* i_chunkPtr, size_t i_chunkSize); - uint8_t* unmarshalChunk(uint8_t* i_tpmBuf, + const uint8_t* unmarshalChunk(const uint8_t* i_tpmBuf, size_t * io_tpmBufSize, void* o_chunkPtr, size_t i_chunkSize) @@ -76,7 +76,7 @@ namespace TRUSTEDBOOT uint8_t* marshalChunk(uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize, - void* i_chunkPtr, + const void* i_chunkPtr, size_t i_chunkSize) { if (NULL != o_tpmBuf) @@ -92,9 +92,10 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal(TPML_TAGGED_TPM_PROPERTY* val, - uint8_t* i_tpmBuf, - size_t* io_tpmBufSize) + const uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal( + TPML_TAGGED_TPM_PROPERTY* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, @@ -108,9 +109,9 @@ namespace TRUSTEDBOOT return i_tpmBuf; } - uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, - uint8_t* i_tpmBuf, - size_t * io_tpmBufSize) + const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, + const uint8_t* i_tpmBuf, + size_t * io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, &(val->capability), @@ -136,7 +137,7 @@ namespace TRUSTEDBOOT return NULL; } - uint8_t* TPMT_HA_marshal(TPMT_HA* val, + uint8_t* TPMT_HA_marshal(const TPMT_HA* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize) @@ -153,24 +154,7 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - size_t TCG_PCR_EVENT_marshalSize(TCG_PCR_EVENT* val) - { - return (sizeof(TCG_PCR_EVENT) + val->eventSize - MAX_TPM_LOG_MSG); - } - - size_t TPMT_HA_marshalSize(TPMT_HA* val) - { - return (sizeof(val->algorithmId) + - getDigestSize((TPM_Alg_Id)(val->algorithmId))); - } - - size_t TPM_EVENT_FIELD_marshalSize(TPM_EVENT_FIELD* val) - { - return (sizeof(val->eventSize) + val->eventSize); - } - - - uint8_t* TPML_DIGEST_VALUES_marshal(TPML_DIGEST_VALUES* val, + uint8_t* TPML_DIGEST_VALUES_marshal(const TPML_DIGEST_VALUES* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize) @@ -198,15 +182,17 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - uint8_t* TPM2_BaseIn_marshal(TPM2_BaseIn* val, uint8_t* o_tpmBuf, + uint8_t* TPM2_BaseIn_marshal(const TPM2_BaseIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) { return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize, val, sizeof(TPM2_BaseIn)); } - uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val, uint8_t* i_tpmBuf, - size_t* io_tpmBufSize, size_t i_outBufSize) + const uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize, + size_t i_outBufSize) { if (sizeof(TPM2_BaseOut) > i_outBufSize) { @@ -216,7 +202,7 @@ namespace TRUSTEDBOOT val, sizeof(TPM2_BaseOut)); } - uint8_t* TPM2_2ByteIn_marshal(TPM2_2ByteIn* val, + uint8_t* TPM2_2ByteIn_marshal(const TPM2_2ByteIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -226,7 +212,7 @@ namespace TRUSTEDBOOT &(val->param), sizeof(val->param)); } - uint8_t* TPM2_4ByteIn_marshal(TPM2_4ByteIn* val, + uint8_t* TPM2_4ByteIn_marshal(const TPM2_4ByteIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -236,7 +222,7 @@ namespace TRUSTEDBOOT &(val->param), sizeof(val->param)); } - uint8_t* TPM2_GetCapabilityIn_marshal(TPM2_GetCapabilityIn* val, + uint8_t* TPM2_GetCapabilityIn_marshal(const TPM2_GetCapabilityIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -254,10 +240,10 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val, - uint8_t* i_tpmBuf, - size_t* io_tpmBufSize, - size_t i_outBufSize) + const uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize, + size_t i_outBufSize) { // Base has already been unmarshaled if (sizeof(TPM2_GetCapabilityOut) > i_outBufSize) @@ -273,7 +259,7 @@ namespace TRUSTEDBOOT } - uint8_t* TPM2_ExtendIn_marshalHandle(TPM2_ExtendIn* val, + uint8_t* TPM2_ExtendIn_marshalHandle(const TPM2_ExtendIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -284,7 +270,7 @@ namespace TRUSTEDBOOT &(val->pcrHandle), sizeof(val->pcrHandle)); } - uint8_t* TPM2_ExtendIn_marshalParms(TPM2_ExtendIn* val, + uint8_t* TPM2_ExtendIn_marshalParms(const TPM2_ExtendIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -294,7 +280,7 @@ namespace TRUSTEDBOOT i_tpmBufSize, io_cmdSize)); } - uint8_t* TPMS_PCR_SELECTION_marshal(TPMS_PCR_SELECTION* val, + uint8_t* TPMS_PCR_SELECTION_marshal(const TPMS_PCR_SELECTION* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -315,9 +301,9 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val, - uint8_t* i_tpmBuf, - size_t* io_tpmBufSize) + const uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, &(val->algorithmId), @@ -336,8 +322,8 @@ namespace TRUSTEDBOOT return i_tpmBuf; } - uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val, - uint8_t* i_tpmBuf, + const uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, @@ -355,8 +341,8 @@ namespace TRUSTEDBOOT } - uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val, - uint8_t* i_tpmBuf, + const uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, @@ -384,7 +370,7 @@ namespace TRUSTEDBOOT } - uint8_t* TPML_PCR_SELECTION_marshal(TPML_PCR_SELECTION* val, + uint8_t* TPML_PCR_SELECTION_marshal(const TPML_PCR_SELECTION* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -415,8 +401,8 @@ namespace TRUSTEDBOOT return o_tpmBuf; } - uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val, - uint8_t* i_tpmBuf, + const uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, @@ -445,7 +431,7 @@ namespace TRUSTEDBOOT } - uint8_t* TPM2_PcrReadIn_marshal(TPM2_PcrReadIn* val, + uint8_t* TPM2_PcrReadIn_marshal(const TPM2_PcrReadIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) @@ -455,8 +441,8 @@ namespace TRUSTEDBOOT i_tpmBufSize, io_cmdSize)); } - uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val, - uint8_t* i_tpmBuf, + const uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize, size_t i_outBufSize) { @@ -474,7 +460,7 @@ namespace TRUSTEDBOOT } - uint8_t* TPMS_AUTH_COMMAND_marshal(TPMS_AUTH_COMMAND* val, + uint8_t* TPMS_AUTH_COMMAND_marshal(const TPMS_AUTH_COMMAND* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize) diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H index b74600652..a22955ede 100644 --- a/src/usr/secureboot/trusted/trustedTypes.H +++ b/src/usr/secureboot/trusted/trustedTypes.H @@ -52,7 +52,6 @@ namespace TRUSTEDBOOT { #endif - /// TPM Algorithm defines typedef enum { @@ -80,7 +79,6 @@ namespace TRUSTEDBOOT HASH_COUNT = 1, ///< Maximum # of digests PCR_SELECT_MAX = (IMPLEMENTATION_PCR+7)/8, ///< PCR selection octet max - }; typedef enum @@ -162,8 +160,10 @@ namespace TRUSTEDBOOT TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES]; } PACKED; typedef struct _TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY; - uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal(TPML_TAGGED_TPM_PROPERTY* val, - uint8_t* i_tpmBuf, size_t* io_tpmBufSize); + const uint8_t* TPML_TAGGED_TPM_PROPERTY_unmarshal( + TPML_TAGGED_TPM_PROPERTY* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize); union _TPMU_CAPABILITIES { @@ -178,8 +178,8 @@ namespace TRUSTEDBOOT TPMU_CAPABILITIES data; ///< The capability data } PACKED; typedef struct _TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA; - uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, - uint8_t* i_tpmBuf, + const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, + const uint8_t* i_tpmBuf, size_t * io_tpmBufSize); @@ -193,10 +193,12 @@ namespace TRUSTEDBOOT uint8_t event[MAX_TPM_LOG_MSG]; ///< The event data } PACKED; typedef struct _TCG_PCR_EVENT TCG_PCR_EVENT; - size_t TCG_PCR_EVENT_marshalSize(TCG_PCR_EVENT* val); - uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val, uint8_t* i_tpmBuf, - size_t i_bufSize, bool* o_err); - uint8_t* TCG_PCR_EVENT_logMarshal(TCG_PCR_EVENT* val, uint8_t* i_logBuf); + size_t TCG_PCR_EVENT_marshalSize(const TCG_PCR_EVENT* val); + const uint8_t* TCG_PCR_EVENT_logUnmarshal(TCG_PCR_EVENT* val, + const uint8_t* i_tpmBuf, + size_t i_bufSize, bool* o_err); + uint8_t* TCG_PCR_EVENT_logMarshal(const TCG_PCR_EVENT* val, + uint8_t* i_logBuf); /// Digest union union _TPMU_HA @@ -212,11 +214,16 @@ namespace TRUSTEDBOOT { uint16_t algorithmId; ///< ID of hashing algorithm TPMU_HA digest; ///< Digest, depends on algorithmid +#ifdef __cplusplus + bool operator==(const _TPMT_HA& i_rhs) const; +#endif } PACKED; typedef struct _TPMT_HA TPMT_HA; - size_t TPMT_HA_marshalSize(TPMT_HA* val); - uint8_t* TPMT_HA_logMarshal(TPMT_HA* val, uint8_t* i_logBuf); - uint8_t* TPMT_HA_marshal(TPMT_HA* val, uint8_t* o_tpmBuf, + size_t TPMT_HA_marshalSize(const TPMT_HA* val); + uint8_t* TPMT_HA_logMarshal(const TPMT_HA* val, uint8_t* i_logBuf); + const uint8_t* TPMT_HA_logUnmarshal(TPMT_HA* val, + const uint8_t* i_tpmBuf, bool* o_err); + uint8_t* TPMT_HA_marshal(const TPMT_HA* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize); @@ -225,12 +232,18 @@ namespace TRUSTEDBOOT { uint32_t count; ///< Number of digests TPMT_HA digests[HASH_COUNT]; ///< Digests +#ifdef __cplusplus + bool operator==(const _TPML_DIGEST_VALUES& i_rhs) const; +#endif } PACKED; typedef struct _TPML_DIGEST_VALUES TPML_DIGEST_VALUES; - size_t TPML_DIGEST_VALUES_marshalSize(TPML_DIGEST_VALUES* val); - uint8_t* TPML_DIGEST_VALUES_logMarshal(TPML_DIGEST_VALUES* val, + size_t TPML_DIGEST_VALUES_marshalSize(const TPML_DIGEST_VALUES* val); + uint8_t* TPML_DIGEST_VALUES_logMarshal(const TPML_DIGEST_VALUES* val, uint8_t* i_logBuf); - uint8_t* TPML_DIGEST_VALUES_marshal(TPML_DIGEST_VALUES* val, + const uint8_t* TPML_DIGEST_VALUES_logUnmarshal(TPML_DIGEST_VALUES* val, + const uint8_t* i_tpmBuf, + bool* o_err); + uint8_t* TPML_DIGEST_VALUES_marshal(const TPML_DIGEST_VALUES* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t * io_cmdSize); @@ -239,11 +252,17 @@ namespace TRUSTEDBOOT { uint32_t eventSize; ///< Size of event data uint8_t event[MAX_TPM_LOG_MSG]; ///< The event data +#ifdef __cplusplus + bool operator==(const _TPM_EVENT_FIELD& i_rhs) const; +#endif } PACKED; typedef struct _TPM_EVENT_FIELD TPM_EVENT_FIELD; - size_t TPM_EVENT_FIELD_marshalSize(TPM_EVENT_FIELD* val); - uint8_t* TPM_EVENT_FIELD_logMarshal(TPM_EVENT_FIELD* val, + size_t TPM_EVENT_FIELD_marshalSize(const TPM_EVENT_FIELD* val); + uint8_t* TPM_EVENT_FIELD_logMarshal(const TPM_EVENT_FIELD* val, uint8_t* i_logBuf); + const uint8_t* TPM_EVENT_FIELD_logUnmarshal(TPM_EVENT_FIELD* val, + const uint8_t* i_tpmBuf, + bool* o_err); /// Crypto agile log entry format struct _TCG_PCR_EVENT2 @@ -252,11 +271,17 @@ namespace TRUSTEDBOOT uint32_t eventType; ///< Type of event TPML_DIGEST_VALUES digests; ///< List of digests extended to PCRIndex TPM_EVENT_FIELD event; ///< Event information +#ifdef __cplusplus + bool operator==(const _TCG_PCR_EVENT2& i_rhs) const; +#endif } PACKED; typedef struct _TCG_PCR_EVENT2 TCG_PCR_EVENT2; - 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); - size_t TCG_PCR_EVENT2_marshalSize(TCG_PCR_EVENT2* val); + 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 TCG_PCR_EVENT2_marshalSize(const TCG_PCR_EVENT2* val); struct _TPM2_BaseIn { @@ -265,7 +290,7 @@ namespace TRUSTEDBOOT uint32_t commandCode; ///< Type TPM_CC_xx } PACKED; typedef struct _TPM2_BaseIn TPM2_BaseIn; - uint8_t* TPM2_BaseIn_marshal(TPM2_BaseIn* val, uint8_t* o_tpmBuf, + uint8_t* TPM2_BaseIn_marshal(const TPM2_BaseIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); /// Base of all outgoing messages @@ -276,7 +301,8 @@ namespace TRUSTEDBOOT uint32_t responseCode; ///< The return code of the operation } PACKED; typedef struct _TPM2_BaseOut TPM2_BaseOut; - uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val, uint8_t* i_tpmBuf, + const uint8_t* TPM2_BaseOut_unmarshal(TPM2_BaseOut* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize, size_t i_outBufSize); /// Generic TPM Input Command structure with a 2 byte param @@ -286,7 +312,7 @@ namespace TRUSTEDBOOT uint16_t param; } PACKED; typedef struct _TPM2_2ByteIn TPM2_2ByteIn; - uint8_t* TPM2_2ByteIn_marshal(TPM2_2ByteIn* val, uint8_t* o_tpmBuf, + uint8_t* TPM2_2ByteIn_marshal(const TPM2_2ByteIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); /// Generic TPM Input Command structure with a 4 byte param @@ -296,7 +322,7 @@ namespace TRUSTEDBOOT uint32_t param; } PACKED; typedef struct _TPM2_4ByteIn TPM2_4ByteIn; - uint8_t* TPM2_4ByteIn_marshal(TPM2_4ByteIn* val, uint8_t* o_tpmBuf, + uint8_t* TPM2_4ByteIn_marshal(const TPM2_4ByteIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); @@ -317,7 +343,7 @@ namespace TRUSTEDBOOT uint32_t propertyCount; ///< Number of properties to return } PACKED; typedef struct _TPM2_GetCapabilityIn TPM2_GetCapabilityIn; - uint8_t* TPM2_GetCapabilityIn_marshal(TPM2_GetCapabilityIn* val, + uint8_t* TPM2_GetCapabilityIn_marshal(const TPM2_GetCapabilityIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); @@ -330,8 +356,8 @@ namespace TRUSTEDBOOT TPMS_CAPABILITY_DATA capData; ///< The capability response } PACKED; typedef struct _TPM2_GetCapabilityOut TPM2_GetCapabilityOut; - uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val, - uint8_t* i_tpmBuf, + const uint8_t* TPM2_GetCapabilityOut_unmarshal(TPM2_GetCapabilityOut* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize, size_t i_outBufSize); @@ -343,10 +369,10 @@ namespace TRUSTEDBOOT TPML_DIGEST_VALUES digests; ///< Values to be extended } PACKED; typedef struct _TPM2_ExtendIn TPM2_ExtendIn; - uint8_t* TPM2_ExtendIn_marshalHandle(TPM2_ExtendIn* val, + uint8_t* TPM2_ExtendIn_marshalHandle(const TPM2_ExtendIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); - uint8_t* TPM2_ExtendIn_marshalParms(TPM2_ExtendIn* val, + uint8_t* TPM2_ExtendIn_marshalParms(const TPM2_ExtendIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); @@ -357,11 +383,11 @@ namespace TRUSTEDBOOT uint8_t pcrSelect[PCR_SELECT_MAX]; } PACKED; typedef struct _TPMS_PCR_SELECTION TPMS_PCR_SELECTION; - uint8_t* TPMS_PCR_SELECTION_marshal(TPMS_PCR_SELECTION* val, + uint8_t* TPMS_PCR_SELECTION_marshal(const TPMS_PCR_SELECTION* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); - uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val, - uint8_t* i_tpmBuf, + const uint8_t* TPMS_PCR_SELECTION_unmarshal(TPMS_PCR_SELECTION* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize); @@ -371,8 +397,9 @@ namespace TRUSTEDBOOT uint8_t buffer[sizeof(TPMU_HA)]; } PACKED; typedef struct _TPM2B_DIGEST TPM2B_DIGEST; - uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val, - uint8_t* i_tpmBuf, size_t* io_tpmBufSize); + const uint8_t* TPM2B_DIGEST_unmarshal(TPM2B_DIGEST* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize); struct _TPML_DIGEST { @@ -380,8 +407,9 @@ namespace TRUSTEDBOOT TPM2B_DIGEST digests[HASH_COUNT]; } PACKED; typedef struct _TPML_DIGEST TPML_DIGEST; - uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val, - uint8_t* i_tpmBuf, size_t* io_tpmBufSize); + const uint8_t* TPML_DIGEST_unmarshal(TPML_DIGEST* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize); struct _TPML_PCR_SELECTION { @@ -389,11 +417,11 @@ namespace TRUSTEDBOOT TPMS_PCR_SELECTION pcrSelections[HASH_COUNT]; } PACKED; typedef struct _TPML_PCR_SELECTION TPML_PCR_SELECTION; - uint8_t* TPML_PCR_SELECTION_marshal(TPML_PCR_SELECTION* val, + uint8_t* TPML_PCR_SELECTION_marshal(const TPML_PCR_SELECTION* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); - uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val, - uint8_t* i_tpmBuf, + const uint8_t* TPML_PCR_SELECTION_unmarshal(TPML_PCR_SELECTION* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize); /// Incoming PCR_Read structure @@ -403,7 +431,7 @@ namespace TRUSTEDBOOT TPML_PCR_SELECTION pcrSelectionIn; } PACKED; typedef struct _TPM2_PcrReadIn TPM2_PcrReadIn; - uint8_t* TPM2_PcrReadIn_marshal(TPM2_PcrReadIn* val, + uint8_t* TPM2_PcrReadIn_marshal(const TPM2_PcrReadIn* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); @@ -416,8 +444,8 @@ namespace TRUSTEDBOOT TPML_DIGEST pcrValues; } PACKED; typedef struct _TPM2_PcrReadOut TPM2_PcrReadOut; - uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val, - uint8_t* i_tpmBuf, + const uint8_t* TPM2_PcrReadOut_unmarshal(TPM2_PcrReadOut* val, + const uint8_t* i_tpmBuf, size_t* io_tpmBufSize, size_t i_outBufSize); @@ -431,7 +459,7 @@ namespace TRUSTEDBOOT uint16_t hmacSize; ///< Size of hmac structure, currently 0 } PACKED; typedef struct _TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND; - uint8_t* TPMS_AUTH_COMMAND_marshal(TPMS_AUTH_COMMAND* val, + uint8_t* TPMS_AUTH_COMMAND_marshal(const TPMS_AUTH_COMMAND* val, uint8_t* o_tpmBuf, size_t i_tpmBufSize, size_t* io_cmdSize); diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index d51c9e031..03d957b9e 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -113,7 +113,11 @@ void* host_update_master_tpm( void *io_pArgs ) } // Now we need to replay any existing entries in the log into the TPM - tpmReplayLog(systemTpms.tpm[TPM_MASTER_INDEX]); + 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) @@ -244,12 +248,78 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target, void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target) { - ///@todo RTC:125288 Implement replay - // Function will walk existing entries in the TPM log and call - // tpmCmdPcrExtend as required - // This function must commit any errors and call tpmMarkFailed if errors - // are found -} + TRACUCOMP(g_trac_trustedboot, ENTER_MRK"tpmReplayLog()"); + errlHndl_t err = NULL; + bool unMarshalError = false; + // Create EVENT2 structure to be populated by getNextEvent() + TCG_PCR_EVENT2 l_eventLog; + // Move past header event to get a pointer to the first event + // If there are no events besides the header, l_eventHndl = NULL + const uint8_t* l_eventHndl = TpmLogMgr_getFirstEvent(io_target.logMgr); + while ( l_eventHndl != NULL ) + { + // Get next event + l_eventHndl = TpmLogMgr_getNextEvent(io_target.logMgr, + l_eventHndl, &l_eventLog, + &unMarshalError); + if (unMarshalError) + { + /*@ + * @errortype + * @reasoncode RC_TPM_UNMARSHALING_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_REPLAY_LOG + * @userdata1 Starting address of event that caused error + * @userdata2 0 + * @devdesc Unmarshal error while replaying tpm log. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_REPLAY_LOG, + RC_TPM_UNMARSHALING_FAIL, + reinterpret_cast(l_eventHndl), + 0, + true /*Add HB SW Callout*/ ); + + err->collectTrace( SECURE_COMP_NAME ); + break; + } + + // Extend to tpm + if (l_eventLog.eventType == EV_ACTION) + { + TRACUBIN(g_trac_trustedboot, "tpmReplayLog: Extending event:", + &l_eventLog, sizeof(TCG_PCR_EVENT2)); + for (size_t i = 0; i < l_eventLog.digests.count; i++) + { + + TPM_Alg_Id l_algId = (TPM_Alg_Id)l_eventLog.digests.digests[i] + .algorithmId; + err = tpmCmdPcrExtend(&io_target, + (TPM_Pcr)l_eventLog.pcrIndex, + l_algId, + l_eventLog.digests.digests[i].digest.bytes, + getDigestSize(l_algId)); + if (err) + { + break; + } + } + if (err) + { + break; + } + } + } + // If the TPM failed we will mark it not functional and commit errl + if (err) + { + tpmMarkFailed(&io_target); + errlCommit(err, SECURE_COMP_ID); + delete err; + err = NULL; + } +} + } // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C index d498af25d..62fec182b 100644 --- a/src/usr/secureboot/trusted/trustedbootCmds.C +++ b/src/usr/secureboot/trusted/trustedbootCmds.C @@ -313,7 +313,7 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode, size_t i_outBufSize) { errlHndl_t err = TB_SUCCESS; - uint8_t* sBuf = i_respBuf; + const uint8_t* sBuf = i_respBuf; int stage = 0; TRACDCOMP( g_trac_trustedboot, diff --git a/src/usr/secureboot/trusted/trustedbootUtils.C b/src/usr/secureboot/trusted/trustedbootUtils.C index e688d2940..25cd56e03 100644 --- a/src/usr/secureboot/trusted/trustedbootUtils.C +++ b/src/usr/secureboot/trusted/trustedbootUtils.C @@ -81,22 +81,6 @@ errlHndl_t tpmTransmit(TpmTarget * io_target, } -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 -- cgit v1.2.1