diff options
author | Chris Engel <cjengel@us.ibm.com> | 2017-07-06 22:04:32 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-08-11 10:04:45 -0400 |
commit | a0e8246b27da999d4d8beba64994daef6333a442 (patch) | |
tree | e86e7042b4442112718aedf90703904a8c4510bf /src/usr/secureboot | |
parent | f08b3735c1402f8fe9292822e1eb95b43357b4ce (diff) | |
download | talos-hostboot-a0e8246b27da999d4d8beba64994daef6333a442.tar.gz talos-hostboot-a0e8246b27da999d4d8beba64994daef6333a442.zip |
MFG support to validate TPM provisioning
Change-Id: I137b6f6c81cbcd3c2379e4ef34ddff021c3cd576
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42835
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Timothy R. Block <block@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot')
-rw-r--r-- | src/usr/secureboot/HBconfig | 5 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedTypes.C | 29 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedTypes.H | 19 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 22 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedbootCmds.C | 159 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedbootCmds.H | 10 |
6 files changed, 242 insertions, 2 deletions
diff --git a/src/usr/secureboot/HBconfig b/src/usr/secureboot/HBconfig index 867bee67c..425593e74 100644 --- a/src/usr/secureboot/HBconfig +++ b/src/usr/secureboot/HBconfig @@ -25,3 +25,8 @@ config DRTM_TRIGGERING #TODO RTC: 170487 Disable for relevant platforms Enable triggering DRTM from Hostboot when the ATTR_FORCE_PRE_PAYLOAD_DRTM attribute is overridden +config TPM_NVIDX_VALIDATE + default y if TPMDD + depends on TPMDD + help + Validate TPM MFG NV Index Provisioning during IPL diff --git a/src/usr/secureboot/trusted/trustedTypes.C b/src/usr/secureboot/trusted/trustedTypes.C index 9e2581ef6..fe8112151 100644 --- a/src/usr/secureboot/trusted/trustedTypes.C +++ b/src/usr/secureboot/trusted/trustedTypes.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -127,6 +127,26 @@ namespace TRUSTEDBOOT return i_tpmBuf; } + const uint8_t* TPML_HANDLE_unmarshal(TPML_HANDLE* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize) + { + i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, + &(val->count), sizeof(val->count)); + + // Now we know the count as well + if (val->count <= MAX_TPML_HANDLES) { + i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, + &(val->handles[0]), + sizeof(uint32_t) * val->count); + } + else + { + return NULL; + } + + return i_tpmBuf; + } const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, const uint8_t* i_tpmBuf, @@ -138,6 +158,13 @@ namespace TRUSTEDBOOT switch (val->capability) { + case TPM_CAP_HANDLES: + { + return TPML_HANDLE_unmarshal( + &(val->data.tpmHandles), i_tpmBuf, + io_tpmBufSize); + } + break; case TPM_CAP_TPM_PROPERTIES: { return TPML_TAGGED_TPM_PROPERTY_unmarshal( diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H index ee19a7200..0798295c5 100644 --- a/src/usr/secureboot/trusted/trustedTypes.H +++ b/src/usr/secureboot/trusted/trustedTypes.H @@ -75,6 +75,10 @@ namespace TRUSTEDBOOT HASH_COUNT = 2, ///< Maximum # of digests PCR_SELECT_MAX = (IMPLEMENTATION_PCR+7)/8, ///< PCR selection octet max + + NVIDX_RSAEKCERT = 0x01C00002, ///< RSA EK certificate NV index + NVIDX_ECCEKCERT = 0x01C0000A, ///< ECC EK certificate NV index + NVIDX_IBMPLATCERT = 0x01C10180, ///< IBM Platform certificate index }; /** @@ -110,9 +114,13 @@ namespace TRUSTEDBOOT TPM_SU_STATE = 0x0001,///< TPM perform restore saved state // Capability + MAX_TPML_HANDLES = 20, + TPM_CAP_HANDLES = 1, MAX_TPM_PROPERTIES = 2, TPM_CAP_TPM_PROPERTIES = 0x00000006, ///< Pull TPM Properties + // TPM Handles + TPM_HT_NV_INDEX = 0x01000000, // TPM Properties TPM_PT_MANUFACTURER = 0x00000105, TPM_PT_FIRMWARE_VERSION_1 = 0x0000010B, @@ -152,10 +160,19 @@ namespace TRUSTEDBOOT TPML_TAGGED_TPM_PROPERTY* val, const uint8_t* i_tpmBuf, size_t* io_tpmBufSize); + struct _TPML_HANDLE + { + uint32_t count; ///< Number of handles + uint32_t handles[MAX_TPML_HANDLES]; + } PACKED; + typedef struct _TPML_HANDLE TPML_HANDLE; + const uint8_t* TPML_HANDLE_unmarshal(TPML_HANDLE* val, + const uint8_t* i_tpmBuf, + size_t* io_tpmBufSize); union _TPMU_CAPABILITIES { - // Currently only TPM properties supported + TPML_HANDLE tpmHandles; TPML_TAGGED_TPM_PROPERTY tpmProperties; } PACKED; typedef union _TPMU_CAPABILITIES TPMU_CAPABILITIES; diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index 6682bf829..083fc0859 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -67,6 +67,7 @@ #include <p9_update_security_ctrl.H> #include <targeting/common/commontargeting.H> #include <algorithm> +#include <util/misc.H> namespace TRUSTEDBOOT { @@ -493,6 +494,27 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget* const i_pTpm) break; } +#ifdef CONFIG_TPM_NVIDX_VALIDATE + // Find out if in manufacturing mode + TARGETING::Target* pTopLevel = nullptr; + TARGETING::targetService().getTopLevelTarget(pTopLevel); + assert(pTopLevel != nullptr,"Top level target was nullptr"); + + auto mnfgFlags = + pTopLevel->getAttr<TARGETING::ATTR_MNFG_FLAGS>(); + + // Only validate during MFG IPL + if (mnfgFlags & TARGETING::MNFG_FLAG_SRC_TERM && + !Util::isSimicsRunning()) { + // TPM_GETCAPABILITY to validate NV Indexes + err = tpmCmdGetCapNvIndexValidate(i_pTpm); + if (nullptr != err) + { + break; + } + } +#endif + #ifdef CONFIG_DRTM // For a DRTM we need to reset PCRs 17-22 if (drtmMpipl) diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C index a052c0571..709675c2d 100644 --- a/src/usr/secureboot/trusted/trustedbootCmds.C +++ b/src/usr/secureboot/trusted/trustedbootCmds.C @@ -447,6 +447,7 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode, return err; } +#ifdef __HOSTBOOT_MODULE errlHndl_t tpmCmdStartup(TpmTarget* io_target) { errlHndl_t err = TB_SUCCESS; @@ -738,6 +739,164 @@ errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target) return err; } +errlHndl_t tpmCmdGetCapNvIndexValidate(TpmTarget* io_target) +{ + errlHndl_t err = TB_SUCCESS; + uint8_t dataBuf[BUFSIZE]; + size_t dataSize = BUFSIZE; + TPM2_GetCapabilityOut* resp = + (TPM2_GetCapabilityOut*)dataBuf; + TPM2_GetCapabilityIn* cmd = + (TPM2_GetCapabilityIn*)dataBuf; + bool foundRSAEKCert = false; + bool foundECCEKCert = false; + bool foundPlatCert = false; + bool moreData = false; + + TRACUCOMP( g_trac_trustedboot, + ">>tpmCmdGetCapNvIndexValidate()" ); + + do + { + + // Build our command block for a get capability of the FW version + memset(dataBuf, 0, dataSize); + + cmd->base.tag = TPM_ST_NO_SESSIONS; + cmd->base.commandCode = TPM_CC_GetCapability; + cmd->capability = TPM_CAP_HANDLES; + cmd->property = TPM_HT_NV_INDEX; + cmd->propertyCount = MAX_TPML_HANDLES; + + err = tpmTransmitCommand(io_target, + dataBuf, + sizeof(dataBuf), + TPM_LOCALITY_0); + + if (TB_SUCCESS != err) + { + TRACFCOMP( g_trac_trustedboot, + "TPM GETCAP Transmit Fail"); + break; + + } + + if (TPM_SUCCESS != resp->base.responseCode) + { + TRACFCOMP( g_trac_trustedboot, + "TPM GETCAP OP Fail Ret(0x%X) Size(%d) ", + resp->base.responseCode, + (int)dataSize); + + /*@ + * @errortype + * @reasoncode RC_TPM_GETCAP_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_CMD_GETCAPNVINDEX + * @userdata1 responseCode + * @userdata2 0 + * @devdesc Command failure reading TPM capability. + * @custdesc Failure detected in security subsystem + */ + err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPNVINDEX, + RC_TPM_GETCAP_FAIL, + resp->base.responseCode, + 0); + + break; + } + + // Walk the reponse data to pull the high order bytes out + + if (resp->capData.capability != TPM_CAP_HANDLES) { + + TRACFCOMP( g_trac_trustedboot, + "TPM GETCAP NVINDEX INVALID DATA " + "Cap(0x%X) Cnt(0x%X) ", + resp->capData.capability, + resp->capData.data.tpmHandles.count); + + /*@ + * @errortype + * @reasoncode RC_TPM_GETCAP_FW_INVALID_RESP + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_CMD_GETCAPNVINDEX + * @userdata1 capability + * @userdata2 0 + * @devdesc Command failure reading TPM NV indexes. + * @custdesc Failure detected in security subsystem + */ + err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPNVINDEX, + RC_TPM_GETCAP_FW_INVALID_RESP, + resp->capData.capability, 0); + + break; + } + + for (size_t idx = 0; idx < resp->capData.data.tpmHandles.count; + ++idx) + { + // Check for specific handles we expect to be setup + // by manufacturing provisioning + switch (resp->capData.data.tpmHandles.handles[idx]) + { + case NVIDX_RSAEKCERT: + foundRSAEKCert = true; + break; + case NVIDX_ECCEKCERT: + foundECCEKCert = true; + break; + case NVIDX_IBMPLATCERT: + foundPlatCert = true; + break; + // Ignore any other handles + } + } + // More Data implies the TPM could have returned more then + // we asked for + moreData = resp->moreData; + + } while ( 0 ); + + // Validate we found all we needed + if (NULL == err && + (foundRSAEKCert == false || foundECCEKCert == false || + foundPlatCert == false || moreData == true)) + { + TRACFCOMP( g_trac_trustedboot, + "TPM GETCAP NVINDEX MISSING INDEX " + "RSAEK(%d) ECCEK(%d) PLAT(%d) MD(%d)", + foundRSAEKCert, foundECCEKCert, foundPlatCert, + moreData); + + /*@ + * @errortype + * @reasoncode RC_TPM_NVINDEX_VALIDATE_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_CMD_GETCAPNVINDEX + * @userdata1[0:3] foundRSAEKCert + * @userdata1[4:7] foundECCEKCert + * @userdata1[8:11] foundPlatCert + * @userdata1[12:31] 0 + * @userdata2[0:3] moreData + * @userdata2[4:31] 0 + * @devdesc Command failure reading TPM NV indexes. + * @custdesc Failure detected in security subsystem + */ + err = tpmCreateErrorLog(MOD_TPM_CMD_GETCAPNVINDEX, + RC_TPM_NVINDEX_VALIDATE_FAIL, + (uint32_t)foundRSAEKCert << 28 | + (uint32_t)foundECCEKCert << 14 | + (uint32_t)foundPlatCert << 20, + (uint32_t)moreData << 28); + } + + TRACDCOMP( g_trac_trustedboot, + "<<tpmCmdGetCapNvIndexValidate() - %s", + ((TB_SUCCESS == err) ? "No Error" : "With Error") ); + return err; +} +#endif // HOSTBOOT errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target, TPM_Pcr i_pcr, diff --git a/src/usr/secureboot/trusted/trustedbootCmds.H b/src/usr/secureboot/trusted/trustedbootCmds.H index b1c1ef0dd..1c40bf80a 100644 --- a/src/usr/secureboot/trusted/trustedbootCmds.H +++ b/src/usr/secureboot/trusted/trustedbootCmds.H @@ -99,6 +99,7 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode, size_t i_respBufSize, TPM2_BaseOut* o_outBuf, size_t i_outBufSize); +#ifdef __HOSTBOOT_MODULE /** * @brief Send the TPM_STARTUP command to the targetted TPM * @param[in/out] io_target Current TPM target structure @@ -117,6 +118,15 @@ errlHndl_t tpmCmdStartup(TpmTarget* io_target); errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target); /** + * @brief Send the TPM_GETCAPABILITY command to validate NV indexes + * @param[in/out] io_target Current TPM target structure + * @return errlHndl_t NULL if successful, otherwise a pointer to the + * error log. +*/ + +errlHndl_t tpmCmdGetCapNvIndexValidate(TpmTarget* io_target); +#endif +/** * @brief Send the TPM_Extend command to the targeted TPM and log * @param[in/out] io_target Current TPM target structure * @param[in] i_pcr PCR to write to |