From 55b2bbc15289496db3c2315ac6d4f5f697095fca Mon Sep 17 00:00:00 2001 From: Nick Bofferding Date: Wed, 15 Mar 2017 17:08:10 -0500 Subject: Converge shadow TPM object into targeting model - Added TPM attributes - Linked TPM attributes to XML models - Updated TpmTarget as alias for TARGETING::Target - Trace all states in TPM targeting target Change-Id: Ic0e6cf974aa82f0273523bdada1081b625cb0ae4 RTC: 168781 CMVC-Coreq: 1021028 CMVC-Prereq: 1021177 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38337 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Michael Baiocchi Tested-by: Jenkins OP Build CI Reviewed-by: Stephen M. Cprek Reviewed-by: Christopher J. Engel Reviewed-by: Daniel M. Crowell --- src/usr/secureboot/trusted/base/trustedboot_base.C | 60 +- src/usr/secureboot/trusted/test/trustedbootTest.H | 220 +++---- src/usr/secureboot/trusted/trustedboot.C | 675 ++++++++++++--------- src/usr/secureboot/trusted/trustedboot.H | 128 ++-- src/usr/secureboot/trusted/trustedbootUtils.C | 2 +- src/usr/secureboot/trusted/trustedbootUtils.H | 7 +- 6 files changed, 649 insertions(+), 443 deletions(-) (limited to 'src/usr/secureboot/trusted') diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C index 8dfe6cb0a..063608f09 100644 --- a/src/usr/secureboot/trusted/base/trustedboot_base.C +++ b/src/usr/secureboot/trusted/base/trustedboot_base.C @@ -55,10 +55,9 @@ // ---------------------------------------------- // Trace definitions // ---------------------------------------------- -#ifdef CONFIG_TPMDD + trace_desc_t* g_trac_trustedboot = nullptr; TRAC_INIT( & g_trac_trustedboot, "TRBOOT", KILOBYTE ); -#endif namespace TRUSTEDBOOT { @@ -67,19 +66,54 @@ namespace TRUSTEDBOOT // Const string to append to PCR extension messages const char* const FW_KEY_HASH_EXT = " FW KEY HASH"; -/// Global object to store TPM status -SystemTpms systemTpms; +/// Global object to store system trusted boot data +SystemData systemData; -TpmTarget::TpmTarget() +#endif + +void getTPMs( + TARGETING::TargetHandleList& o_tpmList, + const TPM_FILTER i_filter) { - memset(this, 0, sizeof(TpmTarget)); - available = true; // Default to available until we know better - mutex_init(&tpmMutex); + TRACUCOMP(g_trac_trustedboot,ENTER_MRK "getTPMs(): i_filter=%d", + i_filter); + + o_tpmList.clear(); + TARGETING::getAllChips( + o_tpmList, + TARGETING::TYPE_TPM, + (i_filter == TPM_FILTER::ALL_IN_BLUEPRINT) ? false : true); + + TRACUCOMP(g_trac_trustedboot,EXIT_MRK "getTPMs(): Found %d TPMs", + o_tpmList.size()); } -#endif +_TpmLogMgr* getTpmLogMgr( + const TpmTarget* const i_pTpm) +{ + assert(i_pTpm != nullptr,"getTpmLogMgr: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "getTpmLogMgr: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + return reinterpret_cast<_TpmLogMgr*>( + i_pTpm->getAttr()); +} +void setTpmLogMgr( + TpmTarget* const i_pTpm, + const _TpmLogMgr* const i_pTpmLogMgr) +{ + assert(i_pTpm != nullptr,"setTpmLogMgr: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "setTpmLogMgr: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + auto pLogMgrPtr = + reinterpret_cast( + i_pTpmLogMgr); + i_pTpm->setAttr< + TARGETING::ATTR_HB_TPM_LOG_MGR_PTR>(pLogMgrPtr); +} errlHndl_t pcrExtendSeparator(bool i_sendAsync) { @@ -97,7 +131,7 @@ errlHndl_t pcrExtendSeparator(bool i_sendAsync) assert(msg !=NULL, "BUG! Message is NULL"); if (!i_sendAsync) { - int rc = msg_sendrecv(systemTpms.msgQ, msg->iv_msg); + int rc = msg_sendrecv(systemData.msgQ, msg->iv_msg); if (0 == rc) { err = msg->iv_errl; @@ -127,7 +161,7 @@ errlHndl_t pcrExtendSeparator(bool i_sendAsync) } else { - int rc = msg_send(systemTpms.msgQ, msg->iv_msg); + int rc = msg_send(systemData.msgQ, msg->iv_msg); if (rc) { /*@ @@ -204,7 +238,7 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr, if (!i_sendAsync) { - int rc = msg_sendrecv(systemTpms.msgQ, msg->iv_msg); + int rc = msg_sendrecv(systemData.msgQ, msg->iv_msg); if (0 == rc) { err = msg->iv_errl; @@ -234,7 +268,7 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr, } else { - int rc = msg_send(systemTpms.msgQ, msg->iv_msg); + int rc = msg_send(systemData.msgQ, msg->iv_msg); if (rc) { /*@ diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H index e4cd3e7bd..04f17e0f0 100755 --- a/src/usr/secureboot/trusted/test/trustedbootTest.H +++ b/src/usr/secureboot/trusted/test/trustedbootTest.H @@ -53,6 +53,11 @@ class TrustedBootTest: public CxxTest::TestSuite { public: + enum TEST_PARAM : size_t + { + EXTEND_PCR_TESTS = 5, + }; + /** * @brief Helper to run failing marshal tests */ @@ -64,14 +69,14 @@ class TrustedBootTest: public CxxTest::TestSuite int64_t & io_num_ops, int64_t & io_fails) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; err = tpmMarshalCommandData(i_cmd, o_outbuf, i_bufsize, &o_cmdSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmMarshalFailTest(%s) - Error not detected", @@ -80,7 +85,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } } @@ -96,7 +101,7 @@ class TrustedBootTest: public CxxTest::TestSuite int64_t & io_fails, size_t i_expSize) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; TRUSTEDBOOT::TPM2_BaseIn* baseCmd = reinterpret_cast(o_outbuf); @@ -109,14 +114,14 @@ class TrustedBootTest: public CxxTest::TestSuite i_bufsize, &o_cmdSize); io_num_ops++; - if (NULL != err) + if (nullptr != err) { io_fails++; TS_FAIL( "runTpmMarshalTest(%s) - Error detected", i_testName); errlCommit( err, TPMDD_COMP_ID ); delete err; - err = NULL; + err = nullptr; break; } io_num_ops++; @@ -138,7 +143,7 @@ class TrustedBootTest: public CxxTest::TestSuite i_expSize-1, &o_cmdSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmMarshalTest(%s) - Size-1 error not detected", @@ -148,7 +153,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } err = tpmMarshalCommandData(i_cmd, @@ -156,7 +161,7 @@ class TrustedBootTest: public CxxTest::TestSuite i_expSize/2, &o_cmdSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmMarshalTest(%s) - Size/2 error not detected", @@ -166,7 +171,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } err = tpmMarshalCommandData(i_cmd, @@ -174,7 +179,7 @@ class TrustedBootTest: public CxxTest::TestSuite i_expSize/3, &o_cmdSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmMarshalTest(%s) - Size/3 error not detected", @@ -184,7 +189,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } } while( 0 ); @@ -203,7 +208,7 @@ class TrustedBootTest: public CxxTest::TestSuite int64_t & io_num_ops, int64_t & io_fails) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; err = tpmUnmarshalResponseData(i_commandCode, i_respBuf, @@ -211,7 +216,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, i_outBufSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmUnmarshalFailTest(%s) - Error not detected", @@ -220,7 +225,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } } @@ -236,7 +241,7 @@ class TrustedBootTest: public CxxTest::TestSuite int64_t & io_num_ops, int64_t & io_fails) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; do { @@ -248,7 +253,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, i_outBufSize); io_num_ops++; - if (NULL != err) + if (nullptr != err) { io_fails++; TS_FAIL( "runTpmUnmarshalTest(%s) - Error detected", @@ -256,7 +261,7 @@ class TrustedBootTest: public CxxTest::TestSuite errlCommit( err, TPMDD_COMP_ID ); delete err; - err = NULL; + err = nullptr; break; } @@ -267,7 +272,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, i_outBufSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmUnmarshalTest(%s) - " @@ -278,7 +283,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } // If the response output buffer is more then just the base we @@ -291,7 +296,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, i_outBufSize); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmUnmarshalTest(%s) - " @@ -302,7 +307,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } } @@ -312,7 +317,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, 4); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmUnmarshalTest(%s) - " @@ -323,7 +328,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } if (i_outBufSize > sizeof(TPM2_BaseOut)) @@ -334,7 +339,7 @@ class TrustedBootTest: public CxxTest::TestSuite o_outBuf, sizeof(TPM2_BaseOut)); io_num_ops++; - if (NULL == err) + if (nullptr == err) { io_fails++; TS_FAIL( "runTpmUnmarshalTest(%s) - " @@ -345,7 +350,7 @@ class TrustedBootTest: public CxxTest::TestSuite else { delete err; - err = NULL; + err = nullptr; } } @@ -690,109 +695,121 @@ class TrustedBootTest: public CxxTest::TestSuite } /** - * @brief Retrieve a node target to test with + * @brief Retrieve present/functional primary TPM target to test with */ - TRUSTEDBOOT::TpmTarget getTestTarget() + TRUSTEDBOOT::TpmTarget* getPrimaryTestTarget() { - TRUSTEDBOOT::TpmTarget target; - TPMDD::tpm_info_t tpmInfo; - - target.available = true; - target.initAttempted = true; - target.failed = false; - - TARGETING::TargetHandleList tpmList; - TARGETING::getAllChips(tpmList, - TARGETING::TYPE_TPM, - false); - if (tpmList.size() > 0) + TRUSTEDBOOT::TpmTarget* pTpm = nullptr; + decltype(pTpm) pTpmToReturn = nullptr; + getPrimaryTpm(pTpm); + if (pTpm) { - target.tpmTarget = tpmList[0]; - TRACFCOMP( g_trac_trustedboot, - "getTestTarget tpm tgt=0x%X", - TARGETING::get_huid(target.tpmTarget)); + "getPrimaryTestTarget: TPM HUID=0x%08X", + TARGETING::get_huid(pTpm)); // Let's see if the requested chip is functional - target.role = TPM_PRIMARY; - errlHndl_t err = tpmReadAttributes (target.tpmTarget, + TPMDD::tpm_info_t tpmInfo; + memset(&tpmInfo,0x00,sizeof(tpmInfo)); + errlHndl_t err = tpmReadAttributes (pTpm, tpmInfo, TPM_LOCALITY_0); - - if (NULL != err) + if (nullptr != err) { - target.failed = true; delete err; + err=nullptr; } else if (!tpmInfo.tpmEnabled) { - TRACFCOMP(g_trac_trustedboot, "getTestTarget - " - "Chip %d not enabled", - target.role); - target.failed = true; + TRACFCOMP(g_trac_trustedboot, "getPrimaryTestTarget: " + "Primary TPM with HUID of 0x%08X and role of %d not " + "enabled", + TARGETING::get_huid(pTpm), + pTpm->getAttr()); } else { - TRACFCOMP(g_trac_trustedboot, "getTestTarget - " - "Chip %d enabled", - target.role); + auto hwasState = pTpm->getAttr(); + if(!hwasState.present || + !hwasState.functional) + { + TRACFCOMP(g_trac_trustedboot, "getPrimaryTestTarget: " + "Primary TPM with HUID of 0x%08X and role of %d not " + "both present and functional", + TARGETING::get_huid(pTpm), + pTpm->getAttr()); + } + else + { + TRACFCOMP(g_trac_trustedboot, "getPrimaryTestTarget: " + "TPM with HUID of 0x%08X and role of %d enabled", + TARGETING::get_huid(pTpm), + pTpm->getAttr()); + pTpmToReturn = pTpm; + } } } - return target; + return pTpmToReturn; } - - /** * @brief TPM Extend PCR */ void testExtendPCR ( void ) { - int64_t fails = 0, num_ops = 0; - uint8_t digest[TPM_ALG_SHA256_SIZE]; - TpmLogMgr logMgr; - TRACFCOMP( g_trac_trustedboot, - "testExtendPCR - Start" ); - TpmTarget target = getTestTarget(); - // Assign our log manager - target.logMgr = &logMgr; + ENTER_MRK "testExtendPCR" ); + + size_t fails = 0; + size_t num_ops = 0; + uint8_t digest[TPM_ALG_SHA256_SIZE]={0}; + TpmLogMgr logMgr; + TpmLogMgr* pSavedTpmLogMgr = nullptr; + bool saved = false; + TpmTarget* pTpm = getPrimaryTestTarget(); do { - - if (target.failed) + if (!pTpm) { - TS_FAIL( "testExtendPCR - Master TPM not functional" ); + TS_FAIL( "testExtendPCR: Primary TPM is not present and " + "functional" ); break; } + // Cache and replace our log manager + pSavedTpmLogMgr = getTpmLogMgr(pTpm); + saved = true; + setTpmLogMgr(pTpm,&logMgr); TpmLogMgr_initialize(&logMgr); - for (size_t idx = 0; idx < sizeof(digest); idx++) + for (size_t idx = 0; idx < sizeof(digest); ++idx) { digest[idx] = idx+1; } - for (size_t i = 0; i < 5; i ++) { + for (size_t i = 0; i < EXTEND_PCR_TESTS; ++i) { num_ops++; - pcrExtendSingleTpm(target, + pcrExtendSingleTpm(pTpm, PCR_DEBUG, TPM_ALG_SHA256, digest, TPM_ALG_SHA256_SIZE, - "testExtendPCR - test 1"); - if( target.failed ) + "testExtendPCR: test"); + + auto hwasState = pTpm->getAttr(); + if(!hwasState.functional) { fails++; - TS_FAIL( "testExtendPCR - Extend Error detected" ); + TS_FAIL( "testExtendPCR: Extend Error detected for " + "iteration %d",i); break; } else { - TRACUCOMP(g_trac_trustedboot, "testExtendPCR - " + TRACUCOMP(g_trac_trustedboot, "testExtendPCR: " "Extend returned as expected."); } } @@ -800,10 +817,15 @@ class TrustedBootTest: public CxxTest::TestSuite } while( 0 ); + + if(saved) + { + setTpmLogMgr(pTpm,pSavedTpmLogMgr); + } + TRACFCOMP( g_trac_trustedboot, - "testExtendPCR - End: %d/%d fails", + EXIT_MRK "testExtendPCR: %d/%d fails", fails, num_ops ); - } /** @@ -811,63 +833,57 @@ class TrustedBootTest: public CxxTest::TestSuite */ void testReadPCR ( void ) { - int64_t fails = 0, num_ops = 0; - uint8_t digest[TPM_ALG_SHA256_SIZE]; - errlHndl_t err = NULL; - TRACFCOMP( g_trac_trustedboot, - "testReadPCR - Start" ); - TpmTarget target = getTestTarget(); + ENTER_MRK "testReadPCR" ); + + size_t fails = 0; + size_t num_ops = 0; + errlHndl_t err = nullptr; + TpmTarget* pTpm = getPrimaryTestTarget(); do { - - if (target.failed) + if (pTpm == nullptr) { - TS_FAIL( "testReadPCR - Master TPM not functional" ); + TS_FAIL( "testReadPCR: Primary TPM is not present and " + "functional" ); break; } + uint8_t digest[TPM_ALG_SHA256_SIZE]={0}; memset(digest, 0, sizeof(digest)); num_ops++; - err = tpmCmdPcrRead(&target, + err = tpmCmdPcrRead(pTpm, PCR_DEBUG, TPM_ALG_SHA256, digest, sizeof(digest)); - if( NULL != err ) + if( nullptr != err ) { fails++; - TS_FAIL( "testReadPCR - Error detected" ); + TS_FAIL( "testReadPCR: Error detected" ); errlCommit( err, SECURE_COMP_ID ); delete err; - err = NULL; + err = nullptr; break; } else { - TRACUCOMP(g_trac_trustedboot, "testReadPCR - " + TRACUCOMP(g_trac_trustedboot, "testReadPCR: " "Read returned as expected."); TRACUBIN(g_trac_trustedboot, "PCR Contents", digest, sizeof(digest)); } - } while( 0 ); + TRACFCOMP( g_trac_trustedboot, - "testReadPCR - End: %d/%d fails", + EXIT_MRK "testReadPCR: %d/%d fails", fails, num_ops ); - - if (NULL != target.logMgr) - { - delete target.logMgr; - } } - - }; #endif diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index b12654748..e92570224 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -63,99 +63,139 @@ #include #include #include +#include +#include namespace TRUSTEDBOOT { -extern SystemTpms systemTpms; +extern SystemData systemData; -void getTPMs( std::list& o_info ) +errlHndl_t getTpmLogDevtreeInfo( + const TpmTarget* const i_pTpm, + uint64_t & io_logAddr, + size_t & o_allocationSize, + uint64_t & o_xscomAddr, + uint32_t & o_i2cMasterOffset) { - TRACUCOMP(g_trac_trustedboot,ENTER_MRK"getTPMs()"); + assert(i_pTpm != nullptr,"getTpmLogDevtreeInfo: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "getTpmLogDevtreeInfo: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); - for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++) - { - if (systemTpms.tpm[idx].available && !systemTpms.tpm[idx].failed) - { - - o_info.push_back(systemTpms.tpm[idx]); - } - } - - TRACUCOMP(g_trac_trustedboot,EXIT_MRK"getTPMs() : Size:%d", o_info.size()); - -} - -errlHndl_t getTpmLogDevtreeInfo(TpmTarget & i_target, - uint64_t & io_logAddr, - size_t & o_allocationSize, - uint64_t & o_xscomAddr, - uint32_t & o_i2cMasterOffset) -{ - errlHndl_t err = NULL; + errlHndl_t err = nullptr; + auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm); TRACUCOMP( g_trac_trustedboot, - ENTER_MRK"getTpmLogDevtreeInfo() tgt=0x%X Addr:%lX %lX", - TARGETING::get_huid(i_target.tpmTarget), - io_logAddr ,(uint64_t)(i_target.logMgr)); + ENTER_MRK"getTpmLogDevtreeInfo() tgt=0x%08X Addr:0x%016lX " + "0x%016lX", + TARGETING::get_huid(i_pTpm), + io_logAddr ,reinterpret_cast(pTpmLogMgr)); o_allocationSize = 0; - if (NULL != i_target.logMgr && - i_target.available) + auto hwasState = i_pTpm->getAttr(); + + if (nullptr != pTpmLogMgr && + hwasState.present) { - err = TpmLogMgr_getDevtreeInfo(i_target.logMgr, + err = TpmLogMgr_getDevtreeInfo(pTpmLogMgr, io_logAddr, o_allocationSize, o_xscomAddr, o_i2cMasterOffset); } TRACUCOMP( g_trac_trustedboot, - EXIT_MRK"getTpmLogDevtreeInfo() Addr:%lX",io_logAddr); + EXIT_MRK"getTpmLogDevtreeInfo() Addr:0x%016lX",io_logAddr); return err; } -void setTpmDevtreeInfo(TpmTarget & i_target, - uint64_t i_xscomAddr, - uint32_t i_i2cMasterOffset) +void setTpmDevtreeInfo( + const TpmTarget* const i_pTpm, + const uint64_t i_xscomAddr, + const uint32_t i_i2cMasterOffset) { + assert(i_pTpm != nullptr,"setTpmLogDevtreeInfo: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "setTpmLogDevtreeInfo: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + TRACUCOMP( g_trac_trustedboot, - ENTER_MRK"setTpmLogDevtreeOffset() tgt=0x%X " - "Xscom:%lX Master:%X", - TARGETING::get_huid(i_target.tpmTarget), + ENTER_MRK"setTpmLogDevtreeOffset() tgt=0x%08X " + "Xscom:0x%016lX Master:0x%08X", + TARGETING::get_huid(i_pTpm), i_xscomAddr, i_i2cMasterOffset); - if (NULL != i_target.logMgr) + auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm); + if (nullptr != pTpmLogMgr) { - TpmLogMgr_setTpmDevtreeInfo(i_target.logMgr, + TpmLogMgr_setTpmDevtreeInfo(pTpmLogMgr, i_xscomAddr, i_i2cMasterOffset); } } +void getTpmWithRoleOf( + TARGETING::TPM_ROLE const i_tpmRole, + TARGETING::Target*& o_pTpm) +{ + o_pTpm = nullptr; + TARGETING::TargetHandleList tpmList; + getTPMs(tpmList,TPM_FILTER::ALL_IN_BLUEPRINT); + + TARGETING::PredicateAttrVal + hasMatchingTpmRole(i_tpmRole); + auto itr = std::find_if(tpmList.begin(),tpmList.end(), + [&hasMatchingTpmRole](const TARGETING::Target* const i_pTpm) + { + return hasMatchingTpmRole(i_pTpm); + }); + if(itr!=tpmList.end()) + { + o_pTpm=*itr; + } +} + +void getPrimaryTpm(TARGETING::Target*& o_pPrimaryTpm) +{ + getTpmWithRoleOf(TARGETING::TPM_ROLE_TPM_PRIMARY, + o_pPrimaryTpm); +} + +void getBackupTpm(TARGETING::Target*& o_pBackupTpm) +{ + getTpmWithRoleOf(TARGETING::TPM_ROLE_TPM_BACKUP, + o_pBackupTpm); +} + bool enabled() { - bool ret = false; + bool enabled = false; #ifdef CONFIG_TPMDD - bool foundFunctional = false; + TARGETING::TargetHandleList tpmList; + getTPMs(tpmList,TPM_FILTER::ALL_IN_BLUEPRINT); - for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++) - { - if ((!systemTpms.tpm[idx].failed && - systemTpms.tpm[idx].available) || - !systemTpms.tpm[idx].initAttempted) + TARGETING::PredicateHwas presentAndFunctional; + presentAndFunctional.present(true); + presentAndFunctional.functional(true); + + TARGETING::PredicateAttrVal + initialized(true); + + auto itr = std::find_if(tpmList.begin(),tpmList.end(), + [&presentAndFunctional,&initialized]( + const TARGETING::Target* const i_pTpm) { - foundFunctional = true; - break; - } - } - // If we have a functional TPM we are enabled - ret = foundFunctional; + return ( presentAndFunctional(i_pTpm) + || !initialized(i_pTpm)); + }); + + enabled = (itr!=tpmList.end()) ? true : false; #endif - return ret; + return enabled; } void* host_update_master_tpm( void *io_pArgs ) { - errlHndl_t err = NULL; + errlHndl_t err = nullptr; bool unlock = false; TRACDCOMP( g_trac_trustedboot, @@ -163,161 +203,168 @@ void* host_update_master_tpm( void *io_pArgs ) TRACUCOMP( g_trac_trustedboot, ENTER_MRK"host_update_master_tpm()"); + // Get all TPMs to setup our array + TARGETING::TargetHandleList tpmList; + getTPMs(tpmList,TPM_FILTER::ALL_IN_BLUEPRINT); + + // Currently we only support a MAX of two TPMS per node + assert(tpmList.size() <= MAX_TPMS_PER_NODE, "Too many TPMs found"); + do { + if (tpmList.empty()) + { + TRACFCOMP( g_trac_trustedboot, + "No TPM Targets found"); + break; + } TARGETING::TargetService& tS = TARGETING::targetService(); - TARGETING::Target* procTarget = NULL; + TARGETING::Target* procTarget = nullptr; err = tS.queryMasterProcChipTargetHandle( procTarget ); - - if (NULL != err) + if (nullptr != err) { break; } - // Now get all TPM's to setup our array - TARGETING::TargetHandleList tpmList; - TARGETING::getAllChips(tpmList, - TARGETING::TYPE_TPM, - true); // ONLY FUNCTIONAL - - // Currently we only support a MAX of two TPMS - assert(tpmList.size() <= 2, "Too many TPMs found"); - - mutex_lock( &(systemTpms.tpm[TPM_MASTER_INDEX].tpmMutex) ); - mutex_lock( &(systemTpms.tpm[TPM_BACKUP_INDEX].tpmMutex) ); - unlock = true; - - systemTpms.tpm[TPM_MASTER_INDEX].role = TPM_PRIMARY; - systemTpms.tpm[TPM_BACKUP_INDEX].role = TPM_BACKUP; - - if (0 == tpmList.size()) + for(auto tpm : tpmList) { - TRACFCOMP( g_trac_trustedboot, - "No TPM Targets found"); - systemTpms.tpm[TPM_MASTER_INDEX].initAttempted = true; - systemTpms.tpm[TPM_MASTER_INDEX].available = false; - systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted = true; - systemTpms.tpm[TPM_BACKUP_INDEX].available = false; + mutex_lock(tpm->getHbMutexAttr()); } - else + unlock = true; + + // Loop through the TPMs and figure out if they are attached + // to the master or alternate master processor + TPMDD::tpm_info_t tpmData; + for (auto tpm : tpmList) { - // Loop through the TPMs and figure out if they are attached - // to the master or alternate processor - TPMDD::tpm_info_t tpmData; - size_t tpmIdx = TPM_MASTER_INDEX; - for (size_t tpmNum = 0; tpmNum < tpmList.size(); tpmNum++) + memset(&tpmData, 0, sizeof(tpmData)); + errlHndl_t readErr = tpmReadAttributes(tpm, + tpmData, + TPM_LOCALITY_0); + if (nullptr != readErr) { - memset(&tpmData, 0, sizeof(tpmData)); - errlHndl_t readErr = tpmReadAttributes(tpmList[tpmNum], - tpmData, - TPM_LOCALITY_0); - if (NULL != readErr) - { - // We are just looking for configured TPMs here - // so we ignore any errors - delete readErr; - readErr = NULL; - } - else - { - // Is the i2c master of this TPM also the master proc? - tpmIdx = (tpmData.i2cTarget == procTarget) ? - TPM_MASTER_INDEX : TPM_BACKUP_INDEX; - - if (NULL != systemTpms.tpm[tpmIdx].tpmTarget) - { - TRACFCOMP( g_trac_trustedboot, - "Duplicate TPM target found %d",tpmIdx); - } - else - { - systemTpms.tpm[tpmIdx].tpmTarget = tpmList[tpmNum]; - systemTpms.tpm[tpmIdx].available = true; - } - } - + // We are just looking for configured TPMs here + // so we ignore any errors + delete readErr; + readErr = nullptr; + } + else + { + // If TPM connected to acting master processor, it is + // primary; otherwise it is backup + TARGETING::TPM_ROLE tpmRole = + (tpmData.i2cTarget == procTarget) ? + TARGETING::TPM_ROLE_TPM_PRIMARY + : TARGETING::TPM_ROLE_TPM_BACKUP; + tpm->setAttr(tpmRole); } } - if (!systemTpms.tpm[TPM_MASTER_INDEX].failed && - systemTpms.tpm[TPM_MASTER_INDEX].available && - NULL != systemTpms.tpm[TPM_MASTER_INDEX].tpmTarget && - TPMDD::tpmPresence(systemTpms.tpm[TPM_MASTER_INDEX].tpmTarget)) + // Initialize primary TPM + TARGETING::Target* pPrimaryTpm = nullptr; + (void)getPrimaryTpm(pPrimaryTpm); + if(pPrimaryTpm) { - // Initialize the TPM, this will mark it as non-functional on fail - tpmInitialize(systemTpms.tpm[TPM_MASTER_INDEX]); + auto hwasState = pPrimaryTpm->getAttr(); + if( hwasState.present + && hwasState.functional) + { + // API call will set TPM init attempted appropriately + tpmInitialize(pPrimaryTpm); + } + else + { + pPrimaryTpm->setAttr< + TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED>(true); + } - } - else - { - // Master TPM doesn't exist in the system - systemTpms.tpm[TPM_MASTER_INDEX].initAttempted = true; - systemTpms.tpm[TPM_MASTER_INDEX].available = false; + // Allocate TPM log if it hasn't been already + auto pTpmLogMgr = getTpmLogMgr(pPrimaryTpm); + // Need to grab state again, as it could have changed + hwasState = pPrimaryTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + if( hwasState.present + && hwasState.functional + && nullptr == pTpmLogMgr) + { + // @todo RTC:145689 For DRTM we locate the previous SRTM log + // and reuse. We must also allocate a DRTM log to be used + pTpmLogMgr = new TpmLogMgr; + setTpmLogMgr(pPrimaryTpm,pTpmLogMgr); + err = TpmLogMgr_initialize(pTpmLogMgr); + if (nullptr != err) + { + hwasState = pPrimaryTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + hwasState.functional = false; + pPrimaryTpm->setAttr( + hwasState); + break; + } + } } - // Allocate the TPM log if it hasn't been already - if (!systemTpms.tpm[TPM_MASTER_INDEX].failed && - systemTpms.tpm[TPM_MASTER_INDEX].available && - NULL == systemTpms.tpm[TPM_MASTER_INDEX].logMgr) + bool primaryTpmAvail = (pPrimaryTpm != nullptr); + if(primaryTpmAvail) { - /// @todo RTC:145689 For DRTM we locate the previous SRTM log and reuse - /// And we must allocate a DRTM log to be used - systemTpms.tpm[TPM_MASTER_INDEX].logMgr = new TpmLogMgr; - err = TpmLogMgr_initialize( - systemTpms.tpm[TPM_MASTER_INDEX].logMgr); - if (NULL != err) + auto primaryHwasState = pPrimaryTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + if (!primaryHwasState.functional || + !primaryHwasState.present) { - systemTpms.tpm[TPM_MASTER_INDEX].initAttempted = true; - systemTpms.tpm[TPM_MASTER_INDEX].failed = true; - break; + primaryTpmAvail = false; } } - if (systemTpms.tpm[TPM_MASTER_INDEX].failed || - !systemTpms.tpm[TPM_MASTER_INDEX].available) + if(!primaryTpmAvail) { - /// @todo RTC:134913 Switch to backup chip if backup TPM avail - // Master TPM not available + // Primary TPM not available TRACFCOMP( g_trac_trustedboot, - "Master TPM Existence Fail"); - + "Primary TPM Existence Fail"); } - // Lastly we will check on the backup TPM and see if it is enabled - // in the attributes at least - if (NULL == systemTpms.tpm[TPM_BACKUP_INDEX].tpmTarget) + TARGETING::Target* pBackupTpm = nullptr; + getBackupTpm(pBackupTpm); + if(pBackupTpm == nullptr) { TRACUCOMP( g_trac_trustedboot, "host_update_master_tpm() " - "Marking backup TPM unavailable " - "due to attribute fail"); - systemTpms.tpm[TPM_BACKUP_INDEX].available = false; - systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted = true; + "Backup TPM unavailable " + "since it's not in the system blueprint."); } else { TPMDD::tpm_info_t tpmInfo; memset(&tpmInfo, 0, sizeof(tpmInfo)); errlHndl_t tmpErr = TPMDD::tpmReadAttributes( - systemTpms.tpm[TPM_BACKUP_INDEX].tpmTarget, + pBackupTpm, tpmInfo, TPM_LOCALITY_0); - if (NULL != tmpErr || !tpmInfo.tpmEnabled) + if (nullptr != tmpErr || !tpmInfo.tpmEnabled) { TRACUCOMP( g_trac_trustedboot, "host_update_master_tpm() " "Marking backup TPM unavailable"); - systemTpms.tpm[TPM_BACKUP_INDEX].available = false; - systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted = true; - if (NULL != tmpErr) + + auto backupHwasState = pBackupTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + backupHwasState.present = false; + backupHwasState.functional = false; + pBackupTpm->setAttr< + TARGETING::ATTR_HWAS_STATE>(backupHwasState); + + + pBackupTpm->setAttr( + true); + if (nullptr != tmpErr) { // Ignore attribute read failure delete tmpErr; - tmpErr = NULL; + tmpErr = nullptr; } } } @@ -326,64 +373,96 @@ void* host_update_master_tpm( void *io_pArgs ) if( unlock ) { - mutex_unlock(&(systemTpms.tpm[TPM_MASTER_INDEX].tpmMutex)); - mutex_unlock(&(systemTpms.tpm[TPM_BACKUP_INDEX].tpmMutex)); + for(auto tpm : tpmList) + { + mutex_unlock(tpm->getHbMutexAttr< + TARGETING::ATTR_HB_TPM_MUTEX>()); + } + unlock = false; } // Make sure we are in a state // where we have a functional TPM TRUSTEDBOOT::tpmVerifyFunctionalTpmExists(); - if (NULL == err) + if (nullptr == err) { // Start the task to start to handle the message queue/extends - task_create(&TRUSTEDBOOT::tpmDaemon, NULL); + task_create(&TRUSTEDBOOT::tpmDaemon, nullptr); } - if (NULL == err) + TARGETING::Target* pPrimaryTpm = nullptr; + (void)getPrimaryTpm(pPrimaryTpm); + + if (nullptr == err) { // Log config entries to TPM - needs to be after mutex_unlock - err = tpmLogConfigEntries(systemTpms.tpm[TPM_MASTER_INDEX]); + if(pPrimaryTpm) + { + err = tpmLogConfigEntries(pPrimaryTpm); + } } - TRACUCOMP( g_trac_trustedboot, - EXIT_MRK"host_update_master_tpm() - " - "Master A:%d F:%d I:%d", - systemTpms.tpm[TPM_MASTER_INDEX].available, - systemTpms.tpm[TPM_MASTER_INDEX].failed, - systemTpms.tpm[TPM_MASTER_INDEX].initAttempted); - TRACUCOMP( g_trac_trustedboot, - EXIT_MRK"host_update_master_tpm() - " - "Backup A:%d F:%d I:%d", - systemTpms.tpm[TPM_BACKUP_INDEX].available, - systemTpms.tpm[TPM_BACKUP_INDEX].failed, - systemTpms.tpm[TPM_BACKUP_INDEX].initAttempted); + if(pPrimaryTpm) + { + TRACUCOMP( g_trac_trustedboot, + "host_update_master_tpm() - " + "Primary TPM Present:%d Functional:%d Init Attempted:%d", + pPrimaryTpm->getAttr(). + present, + pPrimaryTpm->getAttr(). + functional, + pPrimaryTpm->getAttr< + TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED>()); + } + + TARGETING::Target* pBackupTpm = nullptr; + (void)getBackupTpm(pBackupTpm); + if(pBackupTpm) + { + TRACUCOMP( g_trac_trustedboot, + "host_update_master_tpm() - " + "Backup TPM Present:%d Functional:%d Init Attempted:%d", + pBackupTpm->getAttr(). + present, + pBackupTpm->getAttr(). + functional, + pBackupTpm->getAttr< + TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED>()); + } TRACDCOMP( g_trac_trustedboot, EXIT_MRK"host_update_master_tpm() - %s", - ((NULL == err) ? "No Error" : "With Error") ); + ((nullptr == err) ? "No Error" : "With Error") ); return err; } - -void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) +void tpmInitialize(TRUSTEDBOOT::TpmTarget* const i_pTpm) { - errlHndl_t err = NULL; + assert(i_pTpm != nullptr,"tpmInitialize: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "tpmInitialize: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + + errlHndl_t err = nullptr; TRACDCOMP( g_trac_trustedboot, ENTER_MRK"tpmInitialize()" ); TRACUCOMP( g_trac_trustedboot, - ENTER_MRK"tpmInitialize() tgt=0x%X", - TARGETING::get_huid(io_target.tpmTarget)); + ENTER_MRK"tpmInitialize() tgt=0x%08X", + TARGETING::get_huid(i_pTpm)); do { - // TPM Initialization sequence - - io_target.initAttempted = true; - io_target.failed = false; - + i_pTpm->setAttr(true); + auto hwasState = i_pTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + hwasState.functional = true; + i_pTpm->setAttr< + TARGETING::ATTR_HWAS_STATE>(hwasState); + + // read + write bool sendStartup = true; #ifdef CONFIG_DRTM @@ -398,16 +477,16 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) if (sendStartup) { // TPM_STARTUP - err = tpmCmdStartup(&io_target); - if (NULL != err) + err = tpmCmdStartup(i_pTpm); + if (nullptr != err) { break; } } // TPM_GETCAPABILITY to read FW Version - err = tpmCmdGetCapFwVersion(&io_target); - if (NULL != err) + err = tpmCmdGetCapFwVersion(i_pTpm); + if (nullptr != err) { break; } @@ -416,8 +495,8 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) // For a DRTM we need to reset PCRs 17-22 if (drtmMpipl) { - err = tpmDrtmReset(io_target); - if (NULL != err) + err = tpmDrtmReset(i_pTpm); + if (nullptr != err) { break; } @@ -428,9 +507,9 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) // If the TPM failed we will mark it not functional - if (NULL != err) + if (nullptr != err) { - tpmMarkFailed(&io_target); + tpmMarkFailed(i_pTpm); // Log this failure errlCommit(err, SECURE_COMP_ID); } @@ -439,22 +518,28 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) EXIT_MRK"tpmInitialize()"); } -void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target) +void tpmReplayLog(TRUSTEDBOOT::TpmTarget* const i_pTpm) { + assert(i_pTpm != nullptr,"tpmReplayLog: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "tpmReplayLog: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + TRACUCOMP(g_trac_trustedboot, ENTER_MRK"tpmReplayLog()"); - errlHndl_t err = NULL; + errlHndl_t err = nullptr; bool unMarshalError = false; // Create EVENT2 structure to be populated by getNextEvent() - TCG_PCR_EVENT2 l_eventLog; + TCG_PCR_EVENT2 l_eventLog = {0}; // 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 ) + // If there are no events besides the header, l_eventHndl = nullptr + auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm); + const uint8_t* l_eventHndl = TpmLogMgr_getFirstEvent(pTpmLogMgr); + while ( l_eventHndl != nullptr ) { // Get next event - l_eventHndl = TpmLogMgr_getNextEvent(io_target.logMgr, + l_eventHndl = TpmLogMgr_getNextEvent(pTpmLogMgr, l_eventHndl, &l_eventLog, &unMarshalError); if (unMarshalError) @@ -489,7 +574,7 @@ void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target) TPM_Alg_Id l_algId = (TPM_Alg_Id)l_eventLog.digests.digests[i] .algorithmId; - err = tpmCmdPcrExtend(&io_target, + err = tpmCmdPcrExtend(i_pTpm, (TPM_Pcr)l_eventLog.pcrIndex, l_algId, reinterpret_cast @@ -509,18 +594,23 @@ void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target) // If the TPM failed we will mark it not functional and commit errl if (err) { - tpmMarkFailed(&io_target); + tpmMarkFailed(i_pTpm); errlCommit(err, SECURE_COMP_ID); delete err; - err = NULL; + err = nullptr; } } -errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) +errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm) { + assert(i_pTpm != nullptr,"tpmLogConfigEntries: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "tpmLogConfigEntries: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + TRACUCOMP(g_trac_trustedboot, ENTER_MRK"tpmLogConfigEntries()"); - errlHndl_t l_err = NULL; + errlHndl_t l_err = nullptr; do { @@ -536,7 +626,7 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) { break; } - TRACFCOMP(g_trac_trustedboot, "security switch value = 0x%X", + TRACFCOMP(g_trac_trustedboot, "security switch value = 0x%016lX", l_securitySwitchValue); // Extend to TPM - PCR_1 memcpy(l_digest, &l_securitySwitchValue, sizeof(l_securitySwitchValue)); @@ -558,7 +648,7 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) // 1 nibble reserved. // 1 nibble minor D uint32_t l_pvr = mmio_pvr_read() & 0xFFFFFFFF; - TRACDCOMP(g_trac_trustedboot, "PVR of chip = 0x%X", l_pvr); + TRACDCOMP(g_trac_trustedboot, "PVR of chip = 0x%08X", l_pvr); // Extend to TPM - PCR_1 memcpy(l_digest, &l_pvr, sizeof(l_pvr)); l_err = pcrExtend(PCR_1, l_digest, sizeof(l_pvr),"PVR of Chip"); @@ -569,8 +659,9 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) memset(l_digest, 0, sizeof(uint64_t)); // Figure out which node we are running on - TARGETING::Target* l_masterProc = NULL; + TARGETING::Target* l_masterProc = nullptr; TARGETING::targetService().masterProcChipTargetHandle(l_masterProc); + TARGETING::EntityPath l_entityPath = l_masterProc->getAttr(); const TARGETING::EntityPath::PathElement l_pathElement = @@ -618,14 +709,19 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target) return l_err; } -void pcrExtendSingleTpm(TpmTarget & io_target, +void pcrExtendSingleTpm(TpmTarget* const i_pTpm, const TPM_Pcr i_pcr, TPM_Alg_Id i_algId, const uint8_t* i_digest, size_t i_digestSize, const char* i_logMsg) { - errlHndl_t err = NULL; + assert(i_pTpm != nullptr,"pcrExtendSingleTpm: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "pcrExtendSingleTpm: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + + errlHndl_t err = nullptr; TCG_PCR_EVENT2 eventLog; bool unlock = false; @@ -652,12 +748,14 @@ void pcrExtendSingleTpm(TpmTarget & io_target, memset(&eventLog, 0, sizeof(eventLog)); do { - mutex_lock( &io_target.tpmMutex ); + mutex_lock( i_pTpm->getHbMutexAttr() ) ; unlock = true; + auto hwasState = i_pTpm->getAttr(); + // Log the event - if (io_target.available && - !io_target.failed) + if (hwasState.present && + hwasState.functional) { // Fill in TCG_PCR_EVENT2 and add to log eventLog = TpmLogMgr_genLogEventPcrExtend(pcr, @@ -668,8 +766,9 @@ void pcrExtendSingleTpm(TpmTarget & io_target, i_logMsg); if(useStaticLog) { - err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog); - if (NULL != err) + auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm); + err = TpmLogMgr_addEvent(pTpmLogMgr,&eventLog); + if (nullptr != err) { break; } @@ -681,7 +780,7 @@ void pcrExtendSingleTpm(TpmTarget & io_target, // Perform the requested extension and also force into the // SHA1 bank - err = tpmCmdPcrExtend2Hash(&io_target, + err = tpmCmdPcrExtend2Hash(i_pTpm, pcr, i_algId, i_digest, @@ -692,10 +791,10 @@ void pcrExtendSingleTpm(TpmTarget & io_target, } } while ( 0 ); - if (NULL != err) + if (nullptr != err) { // We failed to extend to this TPM we can no longer use it - tpmMarkFailed(&io_target); + tpmMarkFailed(i_pTpm); // Log this failure errlCommit(err, SECURE_COMP_ID); @@ -703,15 +802,20 @@ void pcrExtendSingleTpm(TpmTarget & io_target, if (unlock) { - mutex_unlock(&io_target.tpmMutex); + mutex_unlock( i_pTpm->getHbMutexAttr() ) ; } return; } -void pcrExtendSeparator(TpmTarget & io_target) +void pcrExtendSeparator(TpmTarget* const i_pTpm) { - errlHndl_t err = NULL; - TCG_PCR_EVENT2 eventLog; + assert(i_pTpm != nullptr,"pcrExtendSeparator: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "pcrExtendSeparator: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + + errlHndl_t err = nullptr; + TCG_PCR_EVENT2 eventLog = {0}; bool unlock = false; // Separators are always the same values @@ -732,7 +836,7 @@ void pcrExtendSeparator(TpmTarget & io_target) memset(&eventLog, 0, sizeof(eventLog)); do { - mutex_lock( &io_target.tpmMutex ); + mutex_lock( i_pTpm->getHbMutexAttr() ) ; unlock = true; std::vector pcrs = @@ -757,9 +861,12 @@ void pcrExtendSeparator(TpmTarget & io_target) for (const auto &pcr : pcrs) { + auto hwasState = i_pTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + // Log the separator - if (io_target.available && - !io_target.failed) + if (hwasState.present && + hwasState.functional) { // Fill in TCG_PCR_EVENT2 and add to log eventLog = TpmLogMgr_genLogEventPcrExtend(pcr, @@ -773,8 +880,9 @@ void pcrExtendSeparator(TpmTarget & io_target) if(useStaticLog) { - err = TpmLogMgr_addEvent(io_target.logMgr,&eventLog); - if (NULL != err) + auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm); + err = TpmLogMgr_addEvent(pTpmLogMgr,&eventLog); + if (nullptr != err) { break; } @@ -786,7 +894,7 @@ void pcrExtendSeparator(TpmTarget & io_target) // allowed to go to the dynamic log // Perform the requested extension - err = tpmCmdPcrExtend2Hash(&io_target, + err = tpmCmdPcrExtend2Hash(i_pTpm, pcr, TPM_ALG_SHA1, sha1_digest, @@ -794,7 +902,7 @@ void pcrExtendSeparator(TpmTarget & io_target) TPM_ALG_SHA256, sha256_digest, sizeof(sha256_digest)); - if (NULL != err) + if (nullptr != err) { break; } @@ -804,10 +912,10 @@ void pcrExtendSeparator(TpmTarget & io_target) } while ( 0 ); - if (NULL != err) + if (nullptr != err) { // We failed to extend to this TPM we can no longer use it - tpmMarkFailed(&io_target); + tpmMarkFailed(i_pTpm); // Log this failure errlCommit(err, SECURE_COMP_ID); @@ -815,22 +923,31 @@ void pcrExtendSeparator(TpmTarget & io_target) if (unlock) { - mutex_unlock(&io_target.tpmMutex); + mutex_unlock( i_pTpm->getHbMutexAttr() ) ; } return; } -void tpmMarkFailed(TpmTarget * io_target) +void tpmMarkFailed(TpmTarget* const i_pTpm) { + assert(i_pTpm != nullptr,"tpmMarkFailed: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "tpmMarkFailed: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + TRACFCOMP( g_trac_trustedboot, ENTER_MRK"tpmMarkFailed() Marking TPM as failed : " - "tgt=0x%X", - TARGETING::get_huid(io_target->tpmTarget)); + "tgt=0x%08X", + TARGETING::get_huid(i_pTpm)); - io_target->failed = true; + auto hwasState = i_pTpm->getAttr< + TARGETING::ATTR_HWAS_STATE>(); + hwasState.functional = false; + i_pTpm->setAttr< + TARGETING::ATTR_HWAS_STATE>(hwasState); #ifdef CONFIG_SECUREBOOT - TARGETING::Target* l_tpm = io_target->tpmTarget; + TARGETING::Target* l_tpm = i_pTpm; errlHndl_t l_err = nullptr; TARGETING::Target* l_proc = nullptr; @@ -861,7 +978,7 @@ void tpmMarkFailed(TpmTarget * io_target) if (l_proc == nullptr) { assert(false,"tpmMarkFailed - TPM with non-existent processor indicates" - " a bad MRW. TPM tgt=0x%X", TARGETING::get_huid(l_tpm)); + " a bad MRW. TPM tgt=0x%08X", TARGETING::get_huid(l_tpm)); } // set ATTR_SECUREBOOT_PROTECT_DECONFIGURED_TPM for the processor @@ -910,8 +1027,8 @@ void tpmMarkFailed(TpmTarget * io_target) if (l_err) { TRACFCOMP(g_trac_trustedboot, - ERR_MRK "Processor tgt=0x%X TPM tgt=0x&X. Deconfiguring processor " - "because future security cannot be guaranteed.", + ERR_MRK "Processor tgt=0x%08X TPM tgt=0x%08X. Deconfiguring " + "processor because future security cannot be guaranteed.", TARGETING::get_huid(l_proc), TARGETING::get_huid(l_tpm)); @@ -960,23 +1077,12 @@ void tpmMarkFailed(TpmTarget * io_target) void tpmVerifyFunctionalTpmExists() { - errlHndl_t err = NULL; - bool foundFunctional = false; - - for (size_t idx = 0; idx < MAX_SYSTEM_TPMS; idx ++) - { - if ((!systemTpms.tpm[idx].failed && - systemTpms.tpm[idx].available) || - !systemTpms.tpm[idx].initAttempted) - { - foundFunctional = true; - break; - } - } + errlHndl_t err = nullptr; + bool foundFunctional = enabled(); - if (!foundFunctional && !systemTpms.failedTpmsPosted) + if (!foundFunctional && !systemData.failedTpmsPosted) { - systemTpms.failedTpmsPosted = true; + systemData.failedTpmsPosted = true; TRACFCOMP( g_trac_trustedboot, "NO FUNCTIONAL TPM FOUND"); @@ -1043,7 +1149,7 @@ void tpmVerifyFunctionalTpmExists() void* tpmDaemon(void* unused) { bool shutdownPending = false; - errlHndl_t err = NULL; + errlHndl_t err = nullptr; // Mark as an independent daemon so if it crashes we terminate task_detach(); @@ -1053,17 +1159,17 @@ void* tpmDaemon(void* unused) // Register shutdown events with init service. // Done at the "end" of shutdown processing. // This will flush any other messages (PCR extends) and terminate task - INITSERVICE::registerShutdownEvent(systemTpms.msgQ, + INITSERVICE::registerShutdownEvent(systemData.msgQ, TRUSTEDBOOT::MSG_TYPE_SHUTDOWN); - Message* tb_msg = NULL; + Message* tb_msg = nullptr; while (true) { - msg_t* msg = msg_wait(systemTpms.msgQ); + msg_t* msg = msg_wait(systemData.msgQ); const MessageType type = static_cast(msg->type); - tb_msg = NULL; + tb_msg = nullptr; TRACUCOMP( g_trac_trustedboot, "TpmDaemon Handle CmdType %d", type); @@ -1075,7 +1181,7 @@ void* tpmDaemon(void* unused) shutdownPending = true; // Un-register message queue from the shutdown - INITSERVICE::unregisterShutdownEvent(systemTpms.msgQ); + INITSERVICE::unregisterShutdownEvent(systemData.msgQ); } break; @@ -1088,16 +1194,17 @@ void* tpmDaemon(void* unused) (tb_msg->iv_data); assert(tb_msg->iv_len == sizeof(TRUSTEDBOOT::PcrExtendMsgData) - && msgData != NULL, "Invalid PCRExtend Message"); + && msgData != nullptr, "Invalid PCRExtend Message"); - for (size_t idx = 0; - idx < TRUSTEDBOOT::MAX_SYSTEM_TPMS; idx++) + TARGETING::TargetHandleList tpmList; + getTPMs(tpmList); + for (auto tpm : tpmList) { // Add the event to this TPM, // if an error occurs the TPM will // be marked as failed and the error log committed TRUSTEDBOOT::pcrExtendSingleTpm( - TRUSTEDBOOT::systemTpms.tpm[idx], + tpm, msgData->mPcrIndex, msgData->mAlgId, msgData->mDigest, @@ -1114,14 +1221,15 @@ void* tpmDaemon(void* unused) { tb_msg = static_cast(msg->extra_data); - for (size_t idx = 0; - idx < TRUSTEDBOOT::MAX_SYSTEM_TPMS; idx++) + TARGETING::TargetHandleList tpmList; + getTPMs(tpmList); + for (auto tpm : tpmList) { // Add the separator to this TPM, // if an error occurs the TPM will // be marked as failed and the error log committed TRUSTEDBOOT::pcrExtendSeparator( - TRUSTEDBOOT::systemTpms.tpm[idx]); + tpm); } // Lastly make sure we are in a state @@ -1136,14 +1244,14 @@ void* tpmDaemon(void* unused) }; // Reply back, if we have a tb_msg do that way - if (NULL != tb_msg) + if (nullptr != tb_msg) { - tb_msg->response(systemTpms.msgQ); + tb_msg->response(systemData.msgQ); } else { // use the HB message type to respond - int rc = msg_respond(systemTpms.msgQ, msg); + int rc = msg_respond(systemData.msgQ, msg); if (rc) { TRACFCOMP( g_trac_trustedboot, @@ -1179,17 +1287,17 @@ void* tpmDaemon(void* unused) } TRACUCOMP( g_trac_trustedboot, EXIT_MRK "TpmDaemon Thread Terminate"); - return NULL; + return nullptr; } bool isTpmRequired() { bool retVal = false; - TARGETING::Target* pTopLevel = NULL; + TARGETING::Target* pTopLevel = nullptr; (void)TARGETING::targetService().getTopLevelTarget(pTopLevel); - assert(pTopLevel != NULL, "Unable to get top level target"); + assert(pTopLevel != nullptr, "Unable to get top level target"); TARGETING::ATTR_TPM_REQUIRED_type tpmRequired = pTopLevel->getAttr(); @@ -1208,7 +1316,7 @@ bool isTpmRequired() SENSOR::SensorBase tpmRequired(TARGETING::SENSOR_NAME_TPM_REQUIRED, pTopLevel); errlHndl_t err = tpmRequired.readSensorData(tpmRequiredData); - if (NULL == err) + if (nullptr == err) { // 0x02 == Asserted bit (TPM is required) if ((tpmRequiredData.event_status & @@ -1225,7 +1333,7 @@ bool isTpmRequired() "Unable to read Tpm Required Sensor : rc = 0x%04X", err->reasonCode()); delete err; - err = NULL; + err = nullptr; retVal = true; } } @@ -1249,20 +1357,25 @@ bool isTpmRequired() #ifdef CONFIG_DRTM -errlHndl_t tpmDrtmReset(TpmTarget& io_target) +errlHndl_t tpmDrtmReset(TpmTarget* const i_pTpm) { + assert(i_pTpm != nullptr,"tpmDrtmReset: BUG! i_pTpm was nullptr"); + assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, + "tpmDrtmReset: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr()); + errlHndl_t err = nullptr; // Send to the TPM size_t len = 0; - err = deviceRead(io_target.tpmTarget, + err = deviceRead(i_pTpm, nullptr, len, DEVICE_TPM_ADDRESS(TPMDD::TPM_OP_DRTMRESET, 0, TPM_LOCALITY_4)); - if (NULL == err) + if (nullptr == err) { /// @todo RTC: 145689 reset the dynamic tpm log } diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H index bb434a260..933435c4c 100644 --- a/src/usr/secureboot/trusted/trustedboot.H +++ b/src/usr/secureboot/trusted/trustedboot.H @@ -58,18 +58,16 @@ namespace TRUSTEDBOOT const size_t DEFAULT_BIN_TRACE_SIZE = 128; /// Common static values -enum +enum TRUSTED_BOOT_LIMITS { - MAX_SYSTEM_TPMS = 2, - TPM_MASTER_INDEX = 0, ///< Index into tpm array for master chip - TPM_BACKUP_INDEX = 1, ///< Index for backup TPM + MAX_TPMS_PER_NODE = 2, }; -/// Class object to store system TPM information -class SystemTpms +/// Class object to store trusted boot system data +class SystemData { public: - SystemTpms(): + SystemData(): msgQ(msg_q_create()), failedTpmsPosted(false) { } @@ -78,15 +76,16 @@ public: msg_q_t msgQ; ///< TrustedBootRp message queue bool failedTpmsPosted; ///< Have we already posted - TpmTarget tpm[MAX_SYSTEM_TPMS]; }; /** - * @brief Initialize the targeted TPM - * @param[in/out] io_target Current TPM target structure -*/ -void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target); + * @brief Initialize the targeted TPM + * + * @param[in] i_pTpm TPM targeting target handle indicating TPM to initialize. + * Function will assert if value is nullptr or is not of TPM type + */ +void tpmInitialize(TRUSTEDBOOT::TpmTarget* i_pTpm); /** * @brief Verify a functional TPM still exists in the system @@ -99,32 +98,38 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target); void tpmVerifyFunctionalTpmExists(); /** - * @brief Replay the entries that exist in the log into the TPM as needed - * @param[in/out] io_target Current TPM target structure + * @brief Replay the entries that exist in the log into the TPM as needed + * + * @param[in] i_pTpm TPM targeting target handle indicating TPM to replay log. + * Function will assert if value is nullptr or is not of TPM type */ -void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target); +void tpmReplayLog(TRUSTEDBOOT::TpmTarget* i_pTpm); /** - * @brief Send config entries to tpm + * @brief Send config entries to TPM * - * @param[in/out] io_target Current TPM target structure + * @param[in] i_pTpm TPM targeting target handle indicating TPM to send config + * entries to. Function will assert if value is nullptr or is not of TPM + * type. * - * @return errlHndl_t NULL if successful, otherwise a pointer to the - * error log. + * @return errlHndl_t nullptr if successful, otherwise pointer to error log */ -errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target); +errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* i_pTpm); /** - * @brief Extend a measurement into a TPM and log - * @param[in/out] io_target Current TPM target structure - * @param[in] i_pcr PCR to write to - * @param[in] i_algId Algorithm to extend - * @param[in] i_digest Digest value to write to PCR - * @param[in] i_digestSize Byte size of i_digest data - * @param[in] i_logMsg Null terminated log message + * @brief Extend a measurement into a TPM and log + * + * @param[in] i_pTpm TPM targeting target handle referring to TPM to log a + * measurement to. Function will assert if value is nullptr or is not of + * TPM type. + * @param[in] i_pcr PCR to write to + * @param[in] i_algId Algorithm to extend + * @param[in] i_digest Digest value to write to PCR + * @param[in] i_digestSize Byte size of i_digest data + * @param[in] i_logMsg Null terminated log message */ -void pcrExtendSingleTpm(TpmTarget & io_target, +void pcrExtendSingleTpm(TpmTarget* i_pTpm, TPM_Pcr i_pcr, TPM_Alg_Id i_algId, const uint8_t* i_digest, @@ -132,18 +137,13 @@ void pcrExtendSingleTpm(TpmTarget & io_target, const char* i_logMsg); /** - * @brief Extend a separator into a TPM and log - * @param[in/out] io_target Current TPM target structure - */ -void pcrExtendSeparator(TpmTarget & io_target); - -/** - * @brief Is the TPM_REQUIRED flag set such that the - * system should not boot without a functional TPM - * @retval true TPM is required to boot - * @retval false TPM is not required, failures should be logged + * @brief Extend a separator into a TPM and log + * + * @param[in] i_pTpm TPM targeting target handle referring to TPM to log a + * extend a separator to. Function will assert if value is nullptr or is + * not of TPM type. */ -bool isTpmRequired(); +void pcrExtendSeparator(TpmTarget* i_pTpm); /** Thread start routine for the TPM Daemon * @param[in] void*, unused @@ -152,13 +152,55 @@ void* tpmDaemon(void* unused); #ifdef CONFIG_DRTM /** - * @brief Initiate a DRTM PCR reset - * @param[in/out] io_target Current TPM target structure - * @return errlHndl_t NULL if successful, otherwise a pointer to the + * @brief Initiate a DRTM PCR reset on the given TPM + * + * @param[in] i_pTpm TPM targeting target handle referring to TPM to DRTM + * reset. Function will assert if value is nullptr or is + * not of TPM type. + * + * @return errlHndl_t nullptr if successful, otherwise a pointer to the * error log. */ -errlHndl_t tpmDrtmReset(TpmTarget & io_target); +errlHndl_t tpmDrtmReset(TpmTarget* i_pTpm); #endif +/** + * @brief Returns a pointer to the TPM's log manger + * + * @param[in] i_pTpm TPM targeting target handle. Function asserts if value is + * nullptr or does not refer to a TPM targeting target. + * + * @return _TpmLogMgr* Pointer to TPM's log manager, or nullptr if log manager + * is not configured. + */ +_TpmLogMgr* getTpmLogMgr( + const TpmTarget* i_pTpm); + +/** + * @brief Sets a TPM's log manger + * + * @param[in] i_pTpm TPM targeting target handle. Function asserts if value is + * nullptr or does not refer to a TPM targeting target. + * + * @param[in] i_pTpmLogMg Pointer to TPM log manager, or nullptr to remove log + * manager. + */ +void setTpmLogMgr( + TpmTarget* i_pTpm, + const _TpmLogMgr* i_pTpmLogMgr); + +/** + * @brief Returns TPM with matching role + * + * @param[in] i_tpmRole Role of the TPM to search for + * + * @param[out] o_pTpm TPM targeting target handle of the TPM with the matching + * role, or nullptr if none found + */ +void getTpmWithRoleOf( + TARGETING::TPM_ROLE i_tpmRole, + TARGETING::Target*& o_pTpm); + + } // end TRUSTEDBOOT namespace #endif diff --git a/src/usr/secureboot/trusted/trustedbootUtils.C b/src/usr/secureboot/trusted/trustedbootUtils.C index 0e29468ac..6ba0d6c19 100644 --- a/src/usr/secureboot/trusted/trustedbootUtils.C +++ b/src/usr/secureboot/trusted/trustedbootUtils.C @@ -64,7 +64,7 @@ errlHndl_t tpmTransmit(TpmTarget * io_target, do { // Send to the TPM - err = deviceRead(io_target->tpmTarget, + err = deviceRead(io_target, io_buffer, i_bufsize, DEVICE_TPM_ADDRESS(TPMDD::TPM_OP_TRANSMIT, diff --git a/src/usr/secureboot/trusted/trustedbootUtils.H b/src/usr/secureboot/trusted/trustedbootUtils.H index 78ae7e053..1ebad2fef 100644 --- a/src/usr/secureboot/trusted/trustedbootUtils.H +++ b/src/usr/secureboot/trusted/trustedbootUtils.H @@ -79,10 +79,11 @@ errlHndl_t tpmCreateErrorLog(const uint8_t i_modId, const uint64_t i_user2); /** - * @brief Mark the TPM as non-functional and take required steps - * @param[in/out] io_target Current TPM target structure + * @brief Mark the TPM as non-functional and take required steps + * + * @param[in] i_pTpm Handle to TPM target */ -void tpmMarkFailed(TpmTarget * io_target); +void tpmMarkFailed(TpmTarget * i_pTpm); #ifdef __cplusplus } // end TRUSTEDBOOT namespace -- cgit v1.2.1