summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/secureboot/trustedboot_reasoncodes.H2
-rw-r--r--src/usr/secureboot/HBconfig5
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.C29
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.H19
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C22
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C159
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.H10
7 files changed, 244 insertions, 2 deletions
diff --git a/src/include/usr/secureboot/trustedboot_reasoncodes.H b/src/include/usr/secureboot/trustedboot_reasoncodes.H
index bdabee5c2..5663ba318 100644
--- a/src/include/usr/secureboot/trustedboot_reasoncodes.H
+++ b/src/include/usr/secureboot/trustedboot_reasoncodes.H
@@ -57,6 +57,7 @@ namespace TRUSTEDBOOT
MOD_TPM_TPMDAEMON = 0x0B,
MOD_TPM_SYNCRESPONSE = 0x0C,
MOD_TPM_SEPARATOR = 0x0D,
+ MOD_TPM_CMD_GETCAPNVINDEX = 0x0E,
MOD_TPMLOGMGR_INITIALIZE = 0x10,
MOD_TPMLOGMGR_ADDEVENT = 0x11,
@@ -90,6 +91,7 @@ namespace TRUSTEDBOOT
RC_SEND_FAIL = SECURE_COMP_ID | 0xB2,
RC_MSGRESPOND_FAIL = SECURE_COMP_ID | 0xB3,
RC_UPDATE_SECURITY_CTRL_HWP_FAIL = SECURE_COMP_ID | 0xB4,
+ RC_TPM_NVINDEX_VALIDATE_FAIL = SECURE_COMP_ID | 0xB5,
};
#ifdef __cplusplus
}
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
OpenPOWER on IntegriCloud