summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted/trustedbootCmds.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/secureboot/trusted/trustedbootCmds.C')
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C357
1 files changed, 356 insertions, 1 deletions
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
index db1dca51e..1aeb387f9 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.C
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -48,6 +48,7 @@
#include "trustedbootUtils.H"
#include "trustedboot.H"
#include "trustedTypes.H"
+#include <secureboot/trustedbootif.H>
#ifdef CONFIG_DRTM
#include <secureboot/drtm.H>
@@ -368,6 +369,8 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
switch (i_commandCode)
{
// Empty response commands
+ case TPM_CC_CreatePrimary:
+ case TPM_CC_FlushContext:
case TPM_CC_Startup:
case TPM_CC_PCR_Extend:
// Nothing to do
@@ -401,6 +404,32 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
}
break;
+ case TPM_CC_NV_Read:
+ {
+ // Read out the TPM NV Data
+ TPM2_NVReadOut* l_respPtr =
+ reinterpret_cast<TPM2_NVReadOut*>(o_outBuf);
+ TPM2_NVReadOut* l_tpmRespData =
+ reinterpret_cast<TPM2_NVReadOut*>(i_respBuf);
+ memcpy(l_tpmRespData->NVData,
+ l_respPtr->NVData,
+ TPM_NV_DATA_SIZE);
+ }
+ break;
+
+ case TPM_CC_Quote:
+ {
+ // Pass back the quote data
+ TPM2_QuoteOut* l_respPtr =
+ reinterpret_cast<TPM2_QuoteOut*>(o_outBuf);
+ TPM2_QuoteOut* l_tpmRespData =
+ reinterpret_cast<TPM2_QuoteOut*>(i_respBuf);
+ memcpy(l_respPtr->quoteData,
+ l_tpmRespData->quoteData,
+ sizeof(l_tpmRespData->base.responseSize));
+ }
+ break;
+
default:
{
// Command code not supported
@@ -1235,6 +1264,332 @@ errlHndl_t tpmCmdPcrRead(TpmTarget* io_target,
}
+errlHndl_t tpmCmdCreateAttestationKeys(TpmTarget* i_target)
+{
+ TRACFCOMP(g_trac_trustedboot,
+ ENTER_MRK"tpmCmdCreateAttestationKeys()");
+ errlHndl_t l_errl = nullptr;
+
+ uint8_t l_dataBuf[BUFSIZE] = {};
+ TPM2_CreatePrimaryIn* l_cmd =
+ reinterpret_cast<TPM2_CreatePrimaryIn*>(l_dataBuf);
+ TPM2_BaseOut* l_resp = reinterpret_cast<TPM2_BaseOut*>(l_dataBuf);
+
+ do {
+ uint64_t l_cmdData[] = { 0x0000000000000400,
+ 0x0000000018002300,
+ 0x0B00050472000000,
+ 0x100018000B000300,
+ 0x1000000000000000,
+ 0 };
+ l_cmd->base.tag = TPM_ST_SESSIONS;
+ l_cmd->base.commandSize = TPM_CREATE_PRIMARY_SIZE;
+ l_cmd->base.commandCode = TPM_CC_CreatePrimary;
+ l_cmd->primaryHandle = TPM_RH_PLATFORM;
+ l_cmd->inSensitive.size = TPM_IN_SENSITIVE_SIZE;
+ l_cmd->inSensitive.sensitive.userAuth = TPM_RS_PW;
+
+ memcpy(l_cmd->inSensitive.sensitive.data, l_cmdData, sizeof(l_cmdData));
+
+ size_t l_dataSize = MAX_TRANSMIT_SIZE;
+
+ l_errl = tpmTransmit(i_target,
+ l_dataBuf,
+ l_cmd->base.commandSize,
+ l_dataSize,
+ TPM_LOCALITY_0);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdCreateAttestationKeys: could not transmit TPM command");
+ break;
+ }
+
+ l_errl = tpmUnmarshalResponseData(TPM_CC_CreatePrimary,
+ l_dataBuf,
+ l_dataSize,
+ l_resp,
+ l_dataSize);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdCreateAttestationKeys: could not unmarshal response data");
+ break;
+ }
+
+ // Check response return code
+ if(TPM_SUCCESS != l_resp->responseCode)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdCreateAttestationKeys: TPM (HUID 0x%x) returned a nonzero return code. Expected RC 0x%x, actual RC 0x%x", TARGETING::get_huid(i_target), TPM_SUCCESS, l_resp->responseCode);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @reasoncode RC_TPM_BAD_RESP
+ * @moduleid MOD_TPM_CMD_CREATE_ATTEST
+ * @userdata1 TPM HUID
+ * @userdata2[0..31] Expected response RC
+ * @userdata2[32..63] Actual response RC
+ * @devdesc Incorrect response from TPM_CC_CreatePrimary
+ * command (see logs for TPM HUID)
+ * @custdesc Trusted boot failure
+ */
+ l_errl = tpmCreateErrorLog(MOD_TPM_CMD_CREATE_ATTEST,
+ RC_TPM_BAD_RESP,
+ TARGETING::get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TPM_SUCCESS,
+ l_resp->responseCode));
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_trustedboot,
+ EXIT_MRK"tpmCmdCreateAttestationKeys()");
+ return l_errl;
+}
+
+errlHndl_t tpmCmdReadAKCertificate(TpmTarget* i_target, AKCertificate_t* o_data)
+{
+ TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmCmdReadAKCertificate()");
+ errlHndl_t l_errl = nullptr;
+
+ size_t l_dataSize = MAX_TRANSMIT_SIZE;
+
+ uint8_t l_dataBuf[l_dataSize] = {};
+ TPM2_NVReadIn* l_cmd = reinterpret_cast<TPM2_NVReadIn*>(l_dataBuf);
+ TPM2_BaseOut* l_resp = reinterpret_cast<TPM2_BaseOut*>(l_dataBuf);
+
+ do {
+ uint64_t l_cmdData[] = { 0x01C1018101C10181,
+ 0x0000000940000009,
+ 0x000000000001F400,
+ 0, };
+ l_cmd->base.tag = TPM_ST_SESSIONS;
+ l_cmd->base.commandSize = TPM_NV_READ_SIZE;
+ l_cmd->base.commandCode = TPM_CC_NV_Read;
+
+ memcpy(l_cmd->data, l_cmdData, sizeof(l_cmdData));
+
+ l_errl = tpmTransmit(i_target,
+ l_dataBuf,
+ l_cmd->base.commandSize,
+ l_dataSize,
+ TPM_LOCALITY_0);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmUnmarshalResponseData(TPM_CC_NV_Read,
+ l_dataBuf,
+ l_dataSize,
+ l_resp,
+ l_dataSize);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdReadAKCertificate: could not unmarshal response data");
+ break;
+ }
+
+ if(TPM_SUCCESS != l_resp->responseCode)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdReadAKCertificate: TPM (HUID 0x%x) returned a nonzero return code. Expected RC 0x%x, actual RC 0x%x", TARGETING::get_huid(i_target), TPM_SUCCESS, l_resp->responseCode);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @reasoncode RC_TPM_BAD_RESP
+ * @moduleid MOD_TPM_CMD_READ_AK_CERT
+ * @userdata1 TPM HUID
+ * @userdata2[0..31] Expected response RC
+ * @userdata2[32..63] Actual response RC
+ * @devdesc Incorrect response from TPM_CC_NV_Read
+ * command (see logs for TPM HUID)
+ * @custdesc Trusted boot failure
+ */
+ l_errl = tpmCreateErrorLog(MOD_TPM_CMD_READ_AK_CERT,
+ RC_TPM_BAD_RESP,
+ TARGETING::get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TPM_SUCCESS,
+ l_resp->responseCode));
+ break;
+ }
+
+ TPM2_NVReadOut* l_read = reinterpret_cast<TPM2_NVReadOut*>(l_resp);
+ // NVRAM holds the AK certificate. Copy out a fixed size of 500 bytes
+ memcpy(*o_data, l_read->NVData, TPM_NV_DATA_SIZE);
+
+ }while(0);
+
+ TRACFCOMP(g_trac_trustedboot, EXIT_MRK"tpmCmdReadAKCertificate()");
+ return l_errl;
+}
+
+errlHndl_t tpmCmdGenerateQuote(TpmTarget* i_target,
+ MasterTpmNonce_t* i_masterNonce,
+ QuoteDataOut* o_data)
+{
+ TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmCmdGenerateQuote()");
+ errlHndl_t l_errl = nullptr;
+
+ size_t l_dataSize = MAX_TRANSMIT_SIZE;
+ uint8_t l_dataBuf[l_dataSize] = {};
+ TPM2_QuoteIn* l_cmd = reinterpret_cast<TPM2_QuoteIn*>(l_dataBuf);
+ TPM2_BaseOut* l_resp = reinterpret_cast<TPM2_BaseOut*>(l_dataBuf);
+
+ do {
+ uint64_t l_tpmiDhObject[] = { 0x8000000000000009,
+ 0x4000000900000000,
+ 0x0000200000000000 };
+ uint16_t l_data = 0x0018;
+
+ l_cmd->base.tag = TPM_ST_SESSIONS;
+ l_cmd->base.commandSize = TPM_QUOTE_SIZE;
+ l_cmd->base.commandCode = TPM_CC_Quote;
+
+ memcpy(l_cmd->quoteData.tpmiDhObject,l_tpmiDhObject,sizeof(l_tpmiDhObject));
+
+ memcpy(l_cmd->quoteData.masterNonce,
+ *i_masterNonce,
+ TPM_NONCE_SIZE_BYTES);
+
+ l_cmd->quoteData.data = l_data;
+ l_cmd->quoteData.inScheme = TPM_ALG_SHA256;
+
+ l_cmd->quoteData.pcrSelection.count = 1;
+ l_cmd->quoteData.pcrSelection.pcrSelections[0].algorithmId = TPM_ALG_SHA256;
+ l_cmd->quoteData.pcrSelection.pcrSelections[0].sizeOfSelect =PCR_SELECT_MAX;
+
+ for(size_t i = PCR_0; i <= PCR_7 ; ++i)
+ {
+ l_cmd->quoteData.pcrSelection.pcrSelections[0].pcrSelect[i/8] =
+ 0x01 << (i % 8);
+ }
+
+ l_errl = tpmTransmit(i_target,
+ l_dataBuf,
+ l_cmd->base.commandSize,
+ l_dataSize,
+ TPM_LOCALITY_0);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdGenerateQuote(): could not transmit TPM command");
+ break;
+ }
+
+ l_errl = tpmUnmarshalResponseData(TPM_CC_Quote,
+ l_dataBuf,
+ l_dataSize,
+ l_resp,
+ l_dataSize);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdGenerateQuote(): could not unmarshal response data");
+ break;
+ }
+
+ if(TPM_SUCCESS != l_resp->responseCode)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdGenerateQuote: TPM (HUID 0x%x) returned a nonzero return code. Expected RC 0x%x, actual RC 0x%x", TARGETING::get_huid(i_target), TPM_SUCCESS, l_resp->responseCode);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @reasoncode RC_TPM_BAD_RESP
+ * @moduleid MOD_TPM_CMD_GEN_QUOTE
+ * @userdata1 TPM HUID
+ * @userdata2[0..31] Expected response RC
+ * @userdata2[32..63] Actual response RC
+ * @devdesc Incorrect response from TPM_CC_Quote
+ * command (see logs for TPM HUID)
+ * @custdesc Trusted boot failure
+ */
+ l_errl = tpmCreateErrorLog(MOD_TPM_CMD_GEN_QUOTE,
+ RC_TPM_BAD_RESP,
+ TARGETING::get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TPM_SUCCESS,
+ l_resp->responseCode));
+ break;
+ }
+
+ TPM2_QuoteOut* l_read = reinterpret_cast<TPM2_QuoteOut*>(l_resp);
+ void* l_quoteDataPtr = &l_read->quoteData;
+
+ // The response size contains the size of the base response structure too,
+ // so subtract that size from the size of the actual quote data.
+ o_data->size = l_read->base.responseSize-sizeof(l_read->base);
+ memcpy(o_data->data, l_quoteDataPtr, o_data->size);
+
+ } while(0);
+
+ TRACFCOMP(g_trac_trustedboot, EXIT_MRK"tpmCmdGenerateQuote()");
+ return l_errl;
+}
+
+errlHndl_t tpmCmdFlushContext(TpmTarget* i_target)
+{
+ TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmCmdFlushContext()");
+ errlHndl_t l_errl = nullptr;
+
+ size_t l_dataSize = MAX_TRANSMIT_SIZE;
+ uint8_t l_dataBuf[l_dataSize] = {};
+
+ TPM2_FlushContextIn* l_cmd =
+ reinterpret_cast<TPM2_FlushContextIn*>(l_dataBuf);
+ TPM2_BaseOut* l_resp = reinterpret_cast<TPM2_BaseOut*>(l_dataBuf);
+ do {
+ l_cmd->base.tag = TPM_ST_NO_SESSIONS;
+ l_cmd->base.commandSize = TPM_FLUSH_CONTEXT_SIZE;
+ l_cmd->base.commandCode = TPM_CC_FlushContext;
+
+ l_cmd->flushHandle = TPM_HT_TRANSIENT;
+
+ l_errl = tpmTransmit(i_target,
+ l_dataBuf,
+ l_cmd->base.commandSize,
+ l_dataSize,
+ TPM_LOCALITY_0);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdFlushContext(): could not transmit TPM command");
+ break;
+ }
+
+ l_errl = tpmUnmarshalResponseData(TPM_CC_FlushContext,
+ l_dataBuf,
+ l_dataSize,
+ l_resp,
+ l_dataSize);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdFlushContext(): could not unmarshal response data");
+ break;
+ }
+
+ if(TPM_SUCCESS != l_resp->responseCode)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdFlushContext: TPM (HUID 0x%x) returned a nonzero return code. Expected RC 0x%x, actual RC 0x%x", TARGETING::get_huid(i_target), TPM_SUCCESS, l_resp->responseCode);
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @reasoncode RC_TPM_BAD_RESP
+ * @moduleid MOD_TPM_CMD_FLUSH_CONTEXT
+ * @userdata1 TPM HUID
+ * @userdata2[0..31] Expected response RC
+ * @userdata2[32..63] Actual response RC
+ * @devdesc Incorrect response from TPM2_FlushContext
+ * command (see logs for TPM HUID)
+ * @custdesc Trusted boot failure
+ */
+ l_errl = tpmCreateErrorLog(MOD_TPM_CMD_FLUSH_CONTEXT,
+ RC_TPM_BAD_RESP,
+ TARGETING::get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TPM_SUCCESS,
+ l_resp->responseCode));
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_trustedboot, EXIT_MRK"tpmCmdFlushContext()");
+ return l_errl;
+}
#ifdef __cplusplus
} // end TRUSTEDBOOT
OpenPOWER on IntegriCloud