diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2017-03-15 17:08:10 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-04-10 13:56:21 -0400 |
commit | 55b2bbc15289496db3c2315ac6d4f5f697095fca (patch) | |
tree | ea0dd71b31305f174e4c2fc5c70f12d6ad4581ed | |
parent | ab70aa5b81d379bbab438fa9dbe09793bd6a5405 (diff) | |
download | talos-hostboot-55b2bbc15289496db3c2315ac6d4f5f697095fca.tar.gz talos-hostboot-55b2bbc15289496db3c2315ac6d4f5f697095fca.zip |
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 <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/include/usr/secureboot/trustedbootif.H | 121 | ||||
-rw-r--r-- | src/usr/devtree/bld_devtree.C | 41 | ||||
-rw-r--r-- | src/usr/hwas/common/deconfigGard.C | 15 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 14 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 62 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 60 | ||||
-rwxr-xr-x | src/usr/secureboot/trusted/test/trustedbootTest.H | 220 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 675 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.H | 128 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedbootUtils.C | 2 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedbootUtils.H | 7 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types_hb.xml | 77 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml | 4 | ||||
-rwxr-xr-x | src/usr/targeting/common/xmltohb/target_types_hb.xml | 16 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/vbu_NIMBUS.system.xml | 4 |
15 files changed, 896 insertions, 550 deletions
diff --git a/src/include/usr/secureboot/trustedbootif.H b/src/include/usr/secureboot/trustedbootif.H index 3a849aed2..6b54cadeb 100644 --- a/src/include/usr/secureboot/trustedbootif.H +++ b/src/include/usr/secureboot/trustedbootif.H @@ -39,33 +39,24 @@ #include <list> #include <pnor/pnorif.H> #include <secureboot/containerheader.H> +#include <targeting/common/commontargeting.H> +#include <targeting/common/utilFilter.H> namespace TRUSTEDBOOT { struct _TpmLogMgr; - /// Enumerations to select TPM - typedef enum - { - TPM_PRIMARY = 0, - TPM_BACKUP = 1, - LAST_CHIP_TYPE, - FIRST_CHIP_TYPE = TPM_PRIMARY - } TPM_role; + // Hostboot code just maps the TpmTarget type, which shared APIs use, as a + // targeting target + typedef TARGETING::Target TpmTarget; - - /// Track system TPM status - struct TpmTarget + /** + * @brief Enum used for the getTPMs API to specify scope of TPMs to return + */ + enum class TPM_FILTER : uint8_t { - TARGETING::Target* tpmTarget; ///< TPM target ptr - TPM_role role; ///< Pri vs Backup - uint8_t initAttempted:1;///< Has TPM init been run - uint8_t available:1; ///< Is TPM physically in system - uint8_t failed:1; ///< Is TPM currently failed - struct _TpmLogMgr* logMgr; ///< Event log manager for TPM - mutex_t tpmMutex; ///< TPM Mutex - - TpmTarget(); + ALL_FUNCTIONAL, ///< Return only functional (and present) TPMs + ALL_IN_BLUEPRINT, ///< Return any TPM in the blueprint }; /// TPM PCR designations @@ -128,39 +119,58 @@ namespace TRUSTEDBOOT errlHndl_t pcrExtendSeparator(bool i_sendAsync = true); /** - * @brief Return a set of information related to every unique - * functional TPM in the system + * @brief Returns list of TPMs in the system meeting the specified critera + * + * @param[out] o_tpmList Vector of TPM targeting target handles meeting the + * criteria specified by the i_filter parameter (functional targets or + * blueprint targets). By default, returns functional targets. * - * @param[out] o_info - list of TPM Information + * @param[in] i_filter Filter specifying scope of TPMs to return. * + * @warning Silently clears caller supplied vector before populating it */ - void getTPMs( std::list<TpmTarget>& o_info ); + void getTPMs( + TARGETING::TargetHandleList& o_tpmList, + TPM_FILTER i_filter = TPM_FILTER::ALL_FUNCTIONAL); /** - * @brief Retrieve TPM log device tree information - * @param[in] i_target TPM target information - * @param[in/out] io_logAddr TPM Log Address - * @param[out] o_allocationSize Total memory allocated for log - * @param[out] o_xscomAddr Chip Xscom Address - * @param[out] o_i2cMasterOffset I2c Master Offset - * @return errlHndl_t NULL if successful, otherwise a pointer to the + * @brief Retrieve TPM log device tree information + * + * @param[in] i_pTpm TPM targeting target handle. Function will assert if + * value is nullptr or is not of TPM type. + * + * @param[in/out] io_logAddr TPM Log Address + * + * @param[out] o_allocationSize Total memory allocated for log + * + * @param[out] o_xscomAddr Chip Xscom Address + * + * @param[out] o_i2cMasterOffset I2c Master Offset + * + * @return errlHndl_t NULL if successful, otherwise a pointer to the * error log. */ - errlHndl_t getTpmLogDevtreeInfo(TpmTarget & i_target, - uint64_t & io_logAddr, - size_t & o_allocationSize, - uint64_t & o_xscomAddr, - uint32_t & o_i2cMasterOffset); + errlHndl_t getTpmLogDevtreeInfo( + const TpmTarget* i_pTpm, + uint64_t& io_logAddr, + size_t& o_allocationSize, + uint64_t& o_xscomAddr, + uint32_t& o_i2cMasterOffset); /** - * @brief Store devtree node information for the TPM - * @param[in] i_target TPM target information - * @param[in] i_xscomAddr Chip Xscom Address - * @param[in] i_i2cMasterOffset i2c Master Offset + * @brief Store devtree node information for the TPM + * + * @param[in] i_pTpm TPM targeting target handle. Function will assert if + * value is nullptr or is not of TPM type. + * + * @param[in] i_xscomAddr Chip Xscom Address + * + * @param[in] i_i2cMasterOffset i2c Master Offset */ - void setTpmDevtreeInfo(TpmTarget & i_target, - uint64_t i_xscomAddr, - uint32_t i_i2cMasterOffset); + void setTpmDevtreeInfo( + const TpmTarget* i_pTpm, + uint64_t i_xscomAddr, + uint32_t i_i2cMasterOffset); /** * @brief Is trustedboot enabled and functional @@ -194,6 +204,31 @@ namespace TRUSTEDBOOT * */ errlHndl_t extendBaseImage(); + /** + * @brief Return the primary TPM, if any + * + * @param[out] o_pPrimaryTpm TPM targeting target handle of the primary + * TPM, or nullptr if none. + */ + void getPrimaryTpm(TARGETING::Target*& o_pPrimaryTpm); + + /** + * @brief Return the backup TPM, if any + * + * @param[out] o_pBackupTpm TPM targeting target handle of the backup + * TPM, or nullptr if none. + */ + void getBackupTpm(TARGETING::Target*& o_pBackupTpm); + + /** + * @brief Returns whether system requires a functional TPM to boot or not + * + * @return bool Whether system requires a functional TPM to boot or not. + * @retval true Functional TPM is required to boot + * @retval false Functional TPM is not required to boot + */ + bool isTpmRequired(); + } // end TRUSTEDBOOT namespace diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C index ec2237f3f..61fc5656b 100644 --- a/src/usr/devtree/bld_devtree.C +++ b/src/usr/devtree/bld_devtree.C @@ -236,8 +236,8 @@ void add_i2c_info( const TARGETING::Target* i_targ, TPMDD::tpm_info_t tpmInfo; errlHndl_t err = NULL; //find all TPMs - std::list<TRUSTEDBOOT::TpmTarget> l_tpmTarget; - TRUSTEDBOOT::getTPMs(l_tpmTarget); + TARGETING::TargetHandleList tpmList; + TRUSTEDBOOT::getTPMs(tpmList); #endif //add any other i2c devices here as needed, e.g. TPM, etc @@ -481,31 +481,26 @@ void add_i2c_info( const TARGETING::Target* i_targ, #ifdef CONFIG_TPMDD - std::list<TRUSTEDBOOT::TpmTarget>::iterator tpm = l_tpmTarget.begin(); - while( tpm != l_tpmTarget.end() ) + for(auto pTpm : tpmList) { - // Lookup i2c info for the TPM - err = TPMDD::tpmReadAttributes(tpm->tpmTarget, tpmInfo, + err = TPMDD::tpmReadAttributes(pTpm, tpmInfo, TPMDD::TPM_LOCALITY_0); if (NULL != err) { // Unable to get info we skip this guy delete err; - tpm = l_tpmTarget.erase(tpm); continue; } // ignore the devices that aren't on the current target if( tpmInfo.i2cTarget != i_targ ) { - tpm = l_tpmTarget.erase(tpm); continue; } // skip the devices that are on a different engine else if( tpmInfo.engine != i2cm->engine ) { - ++tpm; continue; } @@ -561,12 +556,12 @@ void add_i2c_info( const TARGETING::Target* i_targ, i_dt->addPropertyCell32(l_tpmNode, "reg", tpmInfo.devAddr >> 1); char l_label[30]; - switch (tpm->role) + switch (pTpm->getAttr<TARGETING::ATTR_TPM_ROLE>()) { - case TRUSTEDBOOT::TPM_PRIMARY: + case TARGETING::TPM_ROLE_TPM_PRIMARY: sprintf( l_label, "tpm" ); break; - case TRUSTEDBOOT::TPM_BACKUP: + case TARGETING::TPM_ROLE_TPM_BACKUP: sprintf( l_label, "tpm-backup" ); break; default: @@ -581,12 +576,9 @@ void add_i2c_info( const TARGETING::Target* i_targ, // Placeholders for the tpm log which will be filled in later // We store info away so we can look up this devtree node later - TRUSTEDBOOT::setTpmDevtreeInfo(*tpm, i_xscomAddr, i2cm->scomAddr); + TRUSTEDBOOT::setTpmDevtreeInfo(pTpm, i_xscomAddr, i2cm->scomAddr); i_dt->addPropertyCell32(l_tpmNode, "linux,sml-size", 0); i_dt->addPropertyCell64(l_tpmNode, "linux,sml-base", 0); - - // now remove the device we added so we don't add it again - tpm = l_tpmTarget.erase(tpm); } // end TPM iter #endif @@ -1271,9 +1263,9 @@ void load_tpmlog(devTree * i_dt, uint64_t& io_address) errlHndl_t l_errl = NULL; // TPM log - std::list<TRUSTEDBOOT::TpmTarget> l_tpmTarget; - TRUSTEDBOOT::getTPMs(l_tpmTarget); - std::list<TRUSTEDBOOT::TpmTarget>::iterator l_tpm = l_tpmTarget.begin(); + TARGETING::TargetHandleList tpmList; + TRUSTEDBOOT::getTPMs(tpmList); + size_t l_allocatedSize = 0; uint32_t* l_propAllocSize = NULL; uint64_t* l_propAddr = NULL; @@ -1285,10 +1277,10 @@ void load_tpmlog(devTree * i_dt, uint64_t& io_address) char l_nodePath[100]; dtOffset_t l_tpmNode; - while( l_tpm != l_tpmTarget.end() ) + for(auto pTpm : tpmList) { - l_errl = TRUSTEDBOOT::getTpmLogDevtreeInfo(*l_tpm, + l_errl = TRUSTEDBOOT::getTpmLogDevtreeInfo(pTpm, io_address, l_allocatedSize, l_scomAddr, @@ -1297,18 +1289,16 @@ void load_tpmlog(devTree * i_dt, uint64_t& io_address) if (l_errl) { errlCommit(l_errl, DEVTREE_COMP_ID); - ++ l_tpm; continue; } // We need to build the devtree path to find this TPM node // Lookup i2c info for the TPM - l_errl = TPMDD::tpmReadAttributes(l_tpm->tpmTarget, l_tpmInfo, + l_errl = TPMDD::tpmReadAttributes(pTpm, l_tpmInfo, TPMDD::TPM_LOCALITY_0); if (l_errl) { errlCommit(l_errl, DEVTREE_COMP_ID); - ++ l_tpm; continue; } @@ -1334,15 +1324,12 @@ void load_tpmlog(devTree * i_dt, uint64_t& io_address) { TRACFCOMP(g_trac_devtree,ERR_MRK" Unable to find " "sml TPM properties"); - ++ l_tpm; continue; } // Store the values in the devtree nodes *l_propAllocSize = l_allocatedSize; *l_propAddr = io_address; - - ++l_tpm; } #endif diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C index 0f250c1f5..b9b1fbf04 100644 --- a/src/usr/hwas/common/deconfigGard.C +++ b/src/usr/hwas/common/deconfigGard.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -48,6 +48,10 @@ #include <ipmi/ipmisensor.H> #endif +#ifdef CONFIG_TPMDD +#include <../../usr/secureboot/trusted/trustedbootUtils.H> +#endif + // Trace definition #define __COMP_TD__ g_trac_deconf @@ -2052,6 +2056,15 @@ void DeconfigGard::_doDeconfigureActions(Target & i_target) { // Placeholder for any necessary deconfigure actions +#ifdef CONFIG_TPMDD + if( i_target.getAttr<TARGETING::ATTR_TYPE>() + == TARGETING::TYPE_TPM) + { + HWAS_INF("_doDeconfigureActions: Deconfiguring TPM 0x%08X", + get_huid(&i_target)); + (void)TRUSTEDBOOT::tpmMarkFailed(&i_target); + } +#endif #ifdef CONFIG_BMC_IPMI // set the BMC status for this target diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 2227c8be2..835d9ea48 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -3813,8 +3813,8 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, #ifdef CONFIG_TPMDD TPMDD::tpm_info_t tpmInfo; errlHndl_t l_err = NULL; - std::list<TRUSTEDBOOT::TpmTarget> l_tpmTarget; - TRUSTEDBOOT::getTPMs(l_tpmTarget); + TARGETING::TargetHandleList tpmList; + TRUSTEDBOOT::getTPMs(tpmList); #endif for( std::list<I2C::MasterInfo_t>::iterator i2cm = l_i2cInfo.begin(); @@ -3872,32 +3872,28 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, } //end of eeprom iter #ifdef CONFIG_TPMDD - std::list<TRUSTEDBOOT::TpmTarget>::iterator l_tpm = l_tpmTarget.begin(); - while( l_tpm != l_tpmTarget.end() ) + for(auto pTpm : tpmList) { DeviceInfo_t l_currentDI; TPMDD::tpm_locality_t locality = TPMDD::TPM_LOCALITY_0; // Lookup i2c info for the TPM - l_err = TPMDD::tpmReadAttributes(l_tpm->tpmTarget, + l_err = TPMDD::tpmReadAttributes(pTpm, tpmInfo, locality); if( NULL != l_err ) { // Unable to get info, so we skip delete l_err; - l_tpm = l_tpmTarget.erase(l_tpm); continue; } // ignore the devices that aren't on the current target if( tpmInfo.i2cTarget != i_i2cMaster ) { - l_tpm = l_tpmTarget.erase(l_tpm); continue; } // skip the devices that are on a different engine else if( tpmInfo.engine != i2cm->engine ) { - ++l_tpm; continue; } @@ -3913,8 +3909,6 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, o_deviceInfo.push_back(l_currentDI); - l_tpm = l_tpmTarget.erase(l_tpm); - } //end of tpm iter #endif diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index e3e0f920b..dba45d701 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -57,6 +57,7 @@ #include <config.h> #include "../hdat/hdattpmdata.H" #include "../secureboot/trusted/tpmLogMgr.H" +#include "../secureboot/trusted/trustedboot.H" namespace RUNTIME @@ -927,16 +928,14 @@ errlHndl_t populate_TpmInfoByNode() auto const l_hdatSbTpmInfo = reinterpret_cast<HDAT::hdatSbTpmInfo_t*> (l_baseAddr + l_currOffset); - std::list<TRUSTEDBOOT::TpmTarget> l_tpmList; - #ifdef CONFIG_TPMDD - TRUSTEDBOOT::getTPMs(l_tpmList); - #endif + TARGETING::TargetHandleList tpmList; + TRUSTEDBOOT::getTPMs(tpmList); TARGETING::TargetHandleList l_procList; getAllChips(l_procList,TARGETING::TYPE_PROC,false); - auto const l_numTpms = l_tpmList.size(); + auto const l_numTpms = tpmList.size(); // fill in the values for the Secure Boot TPM Info Array Header l_hdatSbTpmInfo->hdatSbTpmArrayOffset = sizeof(*l_hdatSbTpmInfo); @@ -947,11 +946,11 @@ errlHndl_t populate_TpmInfoByNode() l_currOffset += sizeof(*l_hdatSbTpmInfo); // fill in the values for each Secure Boot TPM Instance Info in the array - for (auto itpm : l_tpmList) + for (auto pTpm : tpmList) { auto l_tpmInstInfo = reinterpret_cast<HDAT::hdatSbTpmInstInfo_t*> (l_baseAddr + l_currOffset); - auto l_tpmInfo = itpm.tpmTarget->getAttr<TARGETING::ATTR_TPM_INFO>(); + auto l_tpmInfo = pTpm->getAttr<TARGETING::ATTR_TPM_INFO>(); TARGETING::PredicateAttrVal<TARGETING::ATTR_PHYS_PATH> hasSameI2cMaster(l_tpmInfo.i2cMasterPath); @@ -975,20 +974,14 @@ errlHndl_t populate_TpmInfoByNode() l_tpmInstInfo->hdatLocality3Addr = l_tpmInfo.devAddrLocality3; l_tpmInstInfo->hdatLocality4Addr = l_tpmInfo.devAddrLocality4; - uint8_t functional = !itpm.failed; - // TODO RTC 168781 Replace above with something like below - // itpm.tpmTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional; + auto hwasState = pTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(); - uint8_t present = itpm.available; - // TODO RTC 168781 Replace above with something like below - // itpm.tpmTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().present; - - if (functional && present) + if (hwasState.functional && hwasState.present) { // present and functional l_tpmInstInfo->hdatFunctionalStatus = HDAT::TpmPresentAndFunctional; } - else if (present) + else if (hwasState.present) { // present and not functional l_tpmInstInfo->hdatFunctionalStatus = HDAT::TpmPresentNonFunctional; @@ -1005,20 +998,37 @@ errlHndl_t populate_TpmInfoByNode() // use the current offset for the beginning of the SRTM event log l_tpmInstInfo->hdatTpmSrtmEventLogOffset = sizeof(*l_tpmInstInfo); - #ifdef CONFIG_TPMDD // copy the contents of the SRTM event log into HDAT picking the // min of log size and log max (to make sure log size never goes - // over the max - memcpy(reinterpret_cast<void*>(l_baseAddr + l_currOffset), - TpmLogMgr_getLogStartPtr(itpm.logMgr), - itpm.logMgr->logSize < TPM_SRTM_EVENT_LOG_MAX ? - itpm.logMgr->logSize : TPM_SRTM_EVENT_LOG_MAX); + // over the max) + auto * const pLogMgr = TRUSTEDBOOT::getTpmLogMgr(pTpm); + size_t logSize = 0; + if(pLogMgr != nullptr) + { + #ifdef CONFIG_TPMDD + auto const * const pLogStart = + TRUSTEDBOOT::TpmLogMgr_getLogStartPtr(pLogMgr); + assert(pLogStart != nullptr,"populate_TpmInfoByNode: BUG! An " + "allocated log manager's log start pointer should never be " + "nullptr"); + + logSize = (pLogMgr->logSize < TPM_SRTM_EVENT_LOG_MAX) ? + pLogMgr->logSize : TPM_SRTM_EVENT_LOG_MAX; + + memcpy(reinterpret_cast<void*>(l_baseAddr + l_currOffset), + pLogStart, + logSize); + #endif + } + else + { + TRACFCOMP( g_trac_runtime, INFO_MRK "populate_TpmInfoByNode: " + "No static log available to propagate for TPM with HUID of " + "0x%08X",TARGETING::get_huid(pTpm)); + } // set the size value for the data that was copied - l_tpmInstInfo->hdatTpmSrtmEventLogEntrySize = itpm.logMgr->logSize; - #else - l_tpmInstInfo->hdatTpmSrtmEventLogEntrySize = 0; - #endif + l_tpmInstInfo->hdatTpmSrtmEventLogEntrySize = logSize; // advance the current offset to account for the SRTM event log l_currOffset += TPM_SRTM_EVENT_LOG_MAX; 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "getTpmLogMgr: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + return reinterpret_cast<_TpmLogMgr*>( + i_pTpm->getAttr<TARGETING::ATTR_HB_TPM_LOG_MGR_PTR>()); +} +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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "setTpmLogMgr: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + auto pLogMgrPtr = + reinterpret_cast<TARGETING::ATTR_HB_TPM_LOG_MGR_PTR_type>( + 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<TRUSTEDBOOT::TPM2_BaseIn*>(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<TARGETING::ATTR_TPM_ROLE>()); } else { - TRACFCOMP(g_trac_trustedboot, "getTestTarget - " - "Chip %d enabled", - target.role); + auto hwasState = pTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(); + 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<TARGETING::ATTR_TPM_ROLE>()); + } + else + { + TRACFCOMP(g_trac_trustedboot, "getPrimaryTestTarget: " + "TPM with HUID of 0x%08X and role of %d enabled", + TARGETING::get_huid(pTpm), + pTpm->getAttr<TARGETING::ATTR_TPM_ROLE>()); + 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<TARGETING::ATTR_HWAS_STATE>(); + 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 <fapi2.H> #include <plat_hwp_invoker.H> #include <p9_update_security_ctrl.H> +#include <targeting/common/commontargeting.H> +#include <algorithm> namespace TRUSTEDBOOT { -extern SystemTpms systemTpms; +extern SystemData systemData; -void getTPMs( std::list<TpmTarget>& 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "getTpmLogDevtreeInfo: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); - 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<uint64_t>(pTpmLogMgr)); o_allocationSize = 0; - if (NULL != i_target.logMgr && - i_target.available) + auto hwasState = i_pTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(); + + 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "setTpmLogDevtreeInfo: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + 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<TARGETING::ATTR_TPM_ROLE> + 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<TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED> + 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<TARGETING::ATTR_HB_TPM_MUTEX>()); } - 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<TARGETING::ATTR_TPM_ROLE>(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<TARGETING::ATTR_HWAS_STATE>(); + 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<TARGETING::ATTR_HWAS_STATE>( + 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<TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED>( + 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<TARGETING::ATTR_HWAS_STATE>(). + present, + pPrimaryTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(). + 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<TARGETING::ATTR_HWAS_STATE>(). + present, + pBackupTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(). + 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "tpmInitialize: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + + 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<TARGETING::ATTR_HB_TPM_INIT_ATTEMPTED>(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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "tpmReplayLog: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + 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<uint8_t*> @@ -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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "tpmLogConfigEntries: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + 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<TARGETING::ATTR_PHYS_PATH>(); 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "pcrExtendSingleTpm: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + + 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<TARGETING::ATTR_HB_TPM_MUTEX>() ) ; unlock = true; + auto hwasState = i_pTpm->getAttr<TARGETING::ATTR_HWAS_STATE>(); + // 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<TARGETING::ATTR_HB_TPM_MUTEX>() ) ; } 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "pcrExtendSeparator: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + + 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<TARGETING::ATTR_HB_TPM_MUTEX>() ) ; unlock = true; std::vector<TPM_Pcr> 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<TARGETING::ATTR_HB_TPM_MUTEX>() ) ; } 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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "tpmMarkFailed: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + 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<MessageType>(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<TRUSTEDBOOT::Message*>(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<TARGETING::ATTR_TPM_REQUIRED>(); @@ -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::ATTR_TYPE>() == TARGETING::TYPE_TPM, + "tpmDrtmReset: BUG! Expected target to be of TPM type, but " + "it was of type 0x%08X",i_pTpm->getAttr<TARGETING::ATTR_TYPE>()); + 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 diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index f43b34688..cfbee18c8 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -1867,4 +1867,81 @@ ID for the sensor number returned with the elog. --> <writeable/> </attribute> +<!-- TPM Attributes --> + +<attribute> + <id>HB_TPM_INIT_ATTEMPTED</id> + <description> + Whether TPM initialization was attempted or not + 0x00 (false) = Did not attempt to initialize TPM + 0x01 (true) = Attempted to initialize TPM + </description> + <simpleType> + <uint8_t></uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + <hbOnly/> +</attribute> + +<enumerationType> + <id>TPM_ROLE</id> + <description> + Enumeration of possible roles a TPM can play within a node. A TPM has + the primary role if it's connected to the acting master processor, + otherwise it has the backup role. + </description> + <enumerator> + <name>TPM_PRIMARY</name> + <value>0</value> + </enumerator> + <enumerator> + <name>TPM_BACKUP</name> + <value>1</value> + </enumerator> +</enumerationType> + +<attribute> + <id>TPM_ROLE</id> + <description> + Whether the TPM is primary or backup within its parent node. It is + dynamically computed during the boot. + </description> + <simpleType> + <uint8_t></uint8_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + <hbOnly/> +</attribute> + +<attribute> + <id>HB_TPM_MUTEX</id> + <description>Mutex to guard TPM access</description> + <simpleType> + <hbmutex> + </hbmutex> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + <hbOnly/> +</attribute> + +<attribute> + <id>HB_TPM_LOG_MGR_PTR</id> + <description>Pointer to TPM log manager</description> + <simpleType> + <uint64_t> + <default>0</default> + </uint64_t> + </simpleType> + <persistency>volatile-zeroed</persistency> + <readable/> + <writeable/> + <hbOnly/> +</attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml index 4bd240c73..927a3632b 100644 --- a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml @@ -283,6 +283,10 @@ </field> </default> </attribute> + <attribute> + <id>TPM_ROLE</id> + <default>TPM_PRIMARY</default> + </attribute> </targetInstance> <!-- Nimbus n0p0 processor chip --> diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 7777eb2ce..d5b743e1f 100755 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -287,4 +287,20 @@ <attribute><id>IPMI_SENSORS</id></attribute> </targetTypeExtension> +<targetTypeExtension> + <id>chip-tpm-cectpm</id> + <attribute> + <id>HB_TPM_LOG_MGR_PTR</id> + </attribute> + <attribute> + <id>HB_TPM_MUTEX</id> + </attribute> + <attribute> + <id>TPM_ROLE</id> + </attribute> + <attribute> + <id>HB_TPM_INIT_ATTEMPTED</id> + </attribute> +</targetTypeExtension> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/vbu_NIMBUS.system.xml b/src/usr/targeting/common/xmltohb/vbu_NIMBUS.system.xml index 609ac5083..15146e720 100644 --- a/src/usr/targeting/common/xmltohb/vbu_NIMBUS.system.xml +++ b/src/usr/targeting/common/xmltohb/vbu_NIMBUS.system.xml @@ -255,6 +255,10 @@ </field> </default> </attribute> + <attribute> + <id>TPM_ROLE</id> + <default>TPM_PRIMARY</default> + </attribute> </targetInstance> <!-- Nimbus n0p0 processor chip --> |