summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/secureboot/trusted')
-rw-r--r--src/usr/secureboot/trusted/base/trustedbootMsg.H48
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C212
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H4
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.H104
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C134
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C357
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.H49
7 files changed, 887 insertions, 21 deletions
diff --git a/src/usr/secureboot/trusted/base/trustedbootMsg.H b/src/usr/secureboot/trusted/base/trustedbootMsg.H
index 95a52a6e4..9789c4fed 100644
--- a/src/usr/secureboot/trusted/base/trustedbootMsg.H
+++ b/src/usr/secureboot/trusted/base/trustedbootMsg.H
@@ -36,6 +36,7 @@
#include <errl/errlentry.H>
#include <sys/msg.h>
#include "../trustedTypes.H"
+#include <secureboot/trustedbootif.H>
namespace TRUSTEDBOOT
{
@@ -57,7 +58,11 @@ namespace TRUSTEDBOOT
MSG_TYPE_SHUTDOWN,
MSG_TYPE_INIT_BACKUP_TPM,
MSG_TYPE_GETRANDOM,
- MSG_TYPE_LAST = MSG_TYPE_GETRANDOM,
+ MSG_TYPE_CREATE_ATT_KEYS,
+ MSG_TYPE_READ_AK_CERT,
+ MSG_TYPE_GEN_QUOTE,
+ MSG_TYPE_FLUSH_CONTEXT,
+ MSG_TYPE_LAST = MSG_TYPE_FLUSH_CONTEXT,
};
/// PCREXTEND message data
@@ -80,6 +85,47 @@ namespace TRUSTEDBOOT
uint8_t* o_randNum; // the random data is populated here
};
+ // Pure Target* cannot be sent as extra_data through a synchronous message
+ // because the act of deleting the sync mesage attempts to delete the ptr
+ // to the target as well, which causes hostboot crashes. This struct is
+ // a simple wrapper around the Target* for the messages requiring just the
+ // TPM target to be passed.
+ struct TpmTargetData
+ {
+ TpmTarget* tpm;
+ TpmTargetData(TpmTarget* i_tpm) :
+ tpm(i_tpm)
+ {
+ }
+ };
+
+ // The struct used to read the AK ceritificate from TPM's NVRAM
+ struct ReadAKCertData
+ {
+ TpmTarget* tpm;
+ AKCertificate_t* data; // The output of NVRAM read
+ ReadAKCertData(TpmTarget* i_tpm, AKCertificate_t* i_data) :
+ tpm(i_tpm), data(i_data)
+ {
+ }
+ };
+
+ // The struct used to generate TPM quote
+ struct GenQuoteData
+ {
+ TpmTarget* tpm;
+ MasterTpmNonce_t* masterNonce; // 32-byte nonce value
+ QuoteDataOut* data; // Output - the quote and signature fields
+ GenQuoteData(TpmTarget* i_tpm,
+ MasterTpmNonce_t* i_masterNonce,
+ QuoteDataOut* o_data) :
+ tpm(i_tpm),
+ masterNonce(i_masterNonce),
+ data(o_data)
+ {
+ }
+ };
+
// Trustedboot message class
class Message
{
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 090cac160..5c68e3c2f 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -850,4 +850,214 @@ errlHndl_t flushTpmQueue()
return l_errl;
}
+errlHndl_t createAttestationKeys(TpmTarget* i_target)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ Message* l_msg = nullptr;
+
+ TpmTargetData* l_data = new TpmTargetData{i_target};
+
+ l_msg = Message::factory(MSG_TYPE_CREATE_ATT_KEYS,
+ sizeof(*l_data),
+ reinterpret_cast<uint8_t*>(l_data),
+ MSG_MODE_SYNC);
+ assert(l_msg != nullptr, "createAttestationKeys: l_msg is nullptr");
+ l_data = nullptr; //l_msg now owns l_data
+
+ int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg);
+ if(l_rc)
+ {
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_CREATE_ATT_KEYS
+ * @reasoncode RC_SENDRECV_FAIL
+ * @userdata1 rc from msg_sendrecv
+ * @userdata2 TPM HUID
+ * @devdesc msg_sendrecv failed for createAttestationKeys
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_CREATE_ATT_KEYS,
+ RC_SENDRECV_FAIL,
+ l_rc,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ }
+ else
+ {
+ l_errl = l_msg->iv_errl;
+ l_msg->iv_errl = nullptr;
+ }
+
+ if(l_msg)
+ {
+ delete l_msg;
+ l_msg = nullptr;
+ }
+
+#endif
+ return l_errl;
+}
+
+errlHndl_t readAKCertificate(TpmTarget* i_target, AKCertificate_t* o_data)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ Message* l_msg = nullptr;
+
+ ReadAKCertData* l_data = new ReadAKCertData {i_target, o_data};
+
+ l_msg = Message::factory(MSG_TYPE_READ_AK_CERT,
+ sizeof(*l_data),
+ reinterpret_cast<uint8_t*>(l_data),
+ MSG_MODE_SYNC);
+ assert(l_msg != nullptr, "readAKCertificate: l_msg is nullptr");
+ l_data = nullptr; // l_msg now owns l_data
+
+ int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg);
+ if(l_rc)
+ {
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_READ_AK_CERT
+ * @reasoncode RC_SENDRECV_FAIL
+ * @userdata1 rc from msg_sendrecv
+ * @userdata2 TPM HUID
+ * @devdesc msg_sendrecv failed for readAKCertificate
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_READ_AK_CERT,
+ RC_SENDRECV_FAIL,
+ l_rc,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ }
+ else
+ {
+ l_errl = l_msg->iv_errl;
+ l_msg->iv_errl = nullptr;
+ }
+
+ if(l_msg)
+ {
+ delete l_msg;
+ l_msg = nullptr;
+ }
+
+#endif
+ return l_errl;
+}
+
+errlHndl_t generateQuote(TpmTarget* i_target,
+ MasterTpmNonce_t* i_masterNonce,
+ QuoteDataOut* o_data)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ Message* l_msg = nullptr;
+
+ GenQuoteData* l_data = new GenQuoteData{i_target, i_masterNonce, o_data};
+
+ l_msg = Message::factory(MSG_TYPE_GEN_QUOTE,
+ sizeof(*l_data),
+ reinterpret_cast<uint8_t*>(l_data),
+ MSG_MODE_SYNC);
+ assert(l_msg != nullptr, "generateQuote: l_msg is nullptr");
+ l_data = nullptr; //l_msg now owns l_data
+
+ int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg);
+ if(l_rc)
+ {
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_GEN_QUOTE
+ * @reasoncode RC_SENDRECV_FAIL
+ * @userdata1 rc from msg_sendrecv
+ * @userdata2 TPM HUID
+ * @devdesc msg_sendrecv failed for generateQuote
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_GEN_QUOTE,
+ RC_SENDRECV_FAIL,
+ l_rc,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ }
+ else
+ {
+ l_errl = l_msg->iv_errl;
+ l_msg->iv_errl = nullptr;
+ }
+
+ if(l_msg)
+ {
+ delete l_msg;
+ l_msg = nullptr;
+ }
+
+#endif
+ return l_errl;
+}
+
+errlHndl_t flushContext(TpmTarget* i_target)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ Message* l_msg = nullptr;
+
+ TpmTargetData* l_data = new TpmTargetData{i_target};
+
+ l_msg = Message::factory(MSG_TYPE_FLUSH_CONTEXT,
+ sizeof(*l_data),
+ reinterpret_cast<uint8_t*>(l_data),
+ MSG_MODE_SYNC);
+ assert(l_msg != nullptr, "flushContext: l_msg is nullptr");
+ l_data = nullptr;
+
+ int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg);
+ if(l_rc)
+ {
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_FLUSH_CONTEXT
+ * @reasoncode RC_SENDRECV_FAIL
+ * @userdata1 rc from msg_sendrecv
+ * @userdata2 TPM HUID
+ * @devdesc msg_sendrecv failed for TPM2_FlushContext
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_FLUSH_CONTEXT,
+ RC_SENDRECV_FAIL,
+ l_rc,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ }
+ else
+ {
+ l_errl = l_msg->iv_errl;
+ l_msg->iv_errl = nullptr;
+ }
+
+ if(l_msg)
+ {
+ delete l_msg;
+ l_msg = nullptr;
+ }
+
+#endif
+ return l_errl;
+}
+
} // end TRUSTEDBOOT
diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H
index 83792cba0..8c1655dd8 100755
--- a/src/usr/secureboot/trusted/test/trustedbootTest.H
+++ b/src/usr/secureboot/trusted/test/trustedbootTest.H
@@ -906,8 +906,8 @@ class TrustedBootTest: public CxxTest::TestSuite
{
uint64_t randNum = 0;
err = TRUSTEDBOOT::GetRandom(pTpm,
- reinterpret_cast<uint8_t*>(&randNum),
- sizeof(randNum));
+ sizeof(randNum),
+ reinterpret_cast<uint8_t*>(&randNum));
num_ops ++;
if(err)
{
diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H
index 34fc0fff5..7efa1d901 100644
--- a/src/usr/secureboot/trusted/trustedTypes.H
+++ b/src/usr/secureboot/trusted/trustedTypes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -52,11 +52,18 @@ namespace TRUSTEDBOOT
{
#endif
+ // TPM Command buffer sizes
+ enum
+ {
+ BUFSIZE = 256,
+ MAX_TRANSMIT_SIZE = 1024, ///< Maximum send/receive transmit size
+ };
+
/// TPM Algorithm defines
typedef enum
{
- TPM_ALG_SHA1 = 0x0004, ///< SHA1 Id
- TPM_ALG_SHA256 = 0x000B, ///< SHA256 Id
+ TPM_ALG_SHA1 = 0x0004, ///< SHA1 Id
+ TPM_ALG_SHA256 = 0x000B, ///< SHA256 Id
TPM_ALG_INVALID_ID ///< Used for error checking
} TPM_Alg_Id;
@@ -103,7 +110,11 @@ namespace TRUSTEDBOOT
TPM_ST_SESSIONS = 0x8002, ///< A command has sessions
// Command Codes
+ TPM_CC_CreatePrimary = 0x00000131,
TPM_CC_Startup = 0x00000144,
+ TPM_CC_NV_Read = 0x0000014E,
+ TPM_CC_Quote = 0x00000158,
+ TPM_CC_FlushContext = 0x00000165,
TPM_CC_GetCapability = 0x0000017A,
TPM_CC_GetRandom = 0x0000017B,
TPM_CC_PCR_Read = 0x0000017E,
@@ -130,12 +141,22 @@ namespace TRUSTEDBOOT
// TPM Return Codes
TPM_SUCCESS = 0x000,
-
TPM_RC_INITIALIZE = 0x100,
// TPM Authorization types
TPM_RS_PW = 0x40000009,
+ TPM_RH_PLATFORM = 0x4000000C,
+
+ // TPM Command Sizes
+ TPM_CREATE_PRIMARY_SIZE = 0x00000041,
+ TPM_IN_SENSITIVE_SIZE = 0x00000009,
+ TPM_NV_READ_SIZE = 0x00000023,
+ TPM_QUOTE_SIZE = 0x0000004B,
+ TPM_FLUSH_CONTEXT_SIZE = 0x0000000E,
+
+ // Transient Objects handle
+ TPM_HT_TRANSIENT = 0x80000000,
};
@@ -484,6 +505,81 @@ namespace TRUSTEDBOOT
uint8_t* o_tpmBuf, size_t i_tpmBufSize,
size_t* io_cmdSize);
+ struct _TPMS_SENSITIVE_CREATE
+ {
+ uint32_t userAuth;
+ uint8_t data[43];
+ } PACKED;
+ typedef struct _TPMS_SENSITIVE_CREATE TPMS_SENSITIVE_CREATE;
+
+ // Structure that contains the sensitive creation data
+ struct _TPM2B_SENSITIVE_CREATE
+ {
+ uint32_t size;
+ TPMS_SENSITIVE_CREATE sensitive;
+ } PACKED;
+ typedef struct _TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE;
+
+ // Incoming CreatePrimary structure
+ struct _TPM2_CreatePrimaryIn
+ {
+ TPM2_BaseIn base;
+ uint32_t primaryHandle;
+ TPM2B_SENSITIVE_CREATE inSensitive;
+ } PACKED;
+ typedef struct _TPM2_CreatePrimaryIn TPM2_CreatePrimaryIn;
+
+ // Incoming NV Read structure
+ struct _TPM2_NVReadIn
+ {
+ TPM2_BaseIn base;
+ uint8_t data[25];
+ } PACKED;
+ typedef struct _TPM2_NVReadIn TPM2_NVReadIn;
+
+ // Outgoing NV Read structure
+ struct _TPM2_NVReadOut
+ {
+ TPM2_BaseOut base;
+ uint8_t NVData[TPM_NV_DATA_SIZE];
+ } PACKED;
+ typedef struct _TPM2_NVReadOut TPM2_NVReadOut;
+
+ // Struct for the data portion of the Quote request
+ struct _TPM2_QuoteData
+ {
+ uint8_t tpmiDhObject[19];
+ MasterTpmNonce_t masterNonce;
+ uint16_t data;
+ uint16_t inScheme;
+ TPML_PCR_SELECTION pcrSelection;
+ } PACKED;
+ typedef struct _TPM2_QuoteData TPM2_QuoteData;
+
+ // Incoming TPM Quote structure
+ struct _TPM2_QuoteIn
+ {
+ TPM2_BaseIn base;
+ TPM2_QuoteData quoteData;
+ } PACKED;
+ typedef struct _TPM2_QuoteIn TPM2_QuoteIn;
+
+ // Outgoing Quote structure
+ struct _TPM2_QuoteOut
+ {
+ TPM2_BaseOut base;
+ uint8_t quoteData[MAX_TRANSMIT_SIZE];
+ } PACKED;
+ typedef struct _TPM2_QuoteOut TPM2_QuoteOut;
+
+ // Incoming Context Flush structure
+ struct _TPM2_FlushContextIn
+ {
+ TPM2_BaseIn base;
+ uint32_t flushHandle;
+ } PACKED;
+ typedef struct _TPM2_FlushContextIn TPM2_FlushContextIn;
+
#ifdef __cplusplus
} // end TRUSTEDBOOT namespace
#endif
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index 0d9ae36c6..1f5e159a2 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -1479,6 +1479,93 @@ void doInitBackupTpm()
}
}
+errlHndl_t doCreateAttKeys(TpmTarget* i_tpm)
+{
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ l_errl = validateTpmHandle(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmCmdCreateAttestationKeys(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+
+ } while(0);
+
+ return l_errl;
+}
+
+errlHndl_t doReadAKCert(TpmTarget* i_tpm, AKCertificate_t* o_data)
+{
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ l_errl = validateTpmHandle(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmCmdReadAKCertificate(i_tpm, o_data);
+ if(l_errl)
+ {
+ break;
+ }
+ } while(0);
+
+ return l_errl;
+}
+
+errlHndl_t doGenQuote(TpmTarget* i_tpm,
+ MasterTpmNonce_t* i_masterNonce,
+ QuoteDataOut* o_data)
+{
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ l_errl = validateTpmHandle(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmCmdGenerateQuote(i_tpm, i_masterNonce, o_data);
+ if(l_errl)
+ {
+ break;
+ }
+ } while(0);
+
+ return l_errl;
+}
+
+errlHndl_t doFlushContext(TpmTarget* i_tpm)
+{
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ l_errl = validateTpmHandle(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmCmdFlushContext(i_tpm);
+ if(l_errl)
+ {
+ break;
+ }
+ } while(0);
+
+ return l_errl;
+}
+
void* tpmDaemon(void* unused)
{
bool shutdownPending = false;
@@ -1690,6 +1777,44 @@ void* tpmDaemon(void* unused)
}
break;
+ case TRUSTEDBOOT::MSG_TYPE_CREATE_ATT_KEYS:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+ TpmTargetData* l_data =
+ reinterpret_cast<TpmTargetData*>(tb_msg->iv_data);
+ tb_msg->iv_errl = doCreateAttKeys(l_data->tpm);
+ }
+ break;
+
+ case TRUSTEDBOOT::MSG_TYPE_READ_AK_CERT:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+ ReadAKCertData* l_data =
+ reinterpret_cast<ReadAKCertData*>(tb_msg->iv_data);
+ tb_msg->iv_errl = doReadAKCert(l_data->tpm, l_data->data);
+ }
+ break;
+
+ case TRUSTEDBOOT::MSG_TYPE_GEN_QUOTE:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+ GenQuoteData* l_data =
+ reinterpret_cast<GenQuoteData*>(tb_msg->iv_data);
+ tb_msg->iv_errl = doGenQuote(l_data->tpm,
+ l_data->masterNonce,
+ l_data->data);
+ }
+ break;
+
+ case TRUSTEDBOOT::MSG_TYPE_FLUSH_CONTEXT:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+ TpmTargetData* l_data =
+ reinterpret_cast<TpmTargetData*>(tb_msg->iv_data);
+ tb_msg->iv_errl = doFlushContext(l_data->tpm);
+ }
+ break;
+
default:
assert(false, "Invalid msg command");
break;
@@ -1955,8 +2080,8 @@ errlHndl_t tpmDrtmReset(TpmTarget* const i_pTpm)
#ifdef CONFIG_TPMDD
errlHndl_t GetRandom(const TpmTarget* i_pTpm,
- uint8_t* o_randNum,
- const size_t i_randNumSize)
+ const size_t i_randNumSize,
+ uint8_t* o_randNum)
{
errlHndl_t err = nullptr;
Message* msg = nullptr;
@@ -2056,8 +2181,8 @@ errlHndl_t poisonTpm(const TpmTarget* i_pTpm)
// Note: GetRandom validates the TPM handle internally and returns an
// error log if invalid
l_errl = GetRandom(i_pTpm,
- reinterpret_cast<uint8_t*>(&l_randNum),
- sizeof(l_randNum));
+ sizeof(l_randNum),
+ reinterpret_cast<uint8_t*>(&l_randNum));
if (l_errl)
{
@@ -2094,5 +2219,4 @@ errlHndl_t poisonTpm(const TpmTarget* i_pTpm)
return l_errl;
}
-
} // end TRUSTEDBOOT
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
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.H b/src/usr/secureboot/trusted/trustedbootCmds.H
index 1c40bf80a..9b0e99aaa 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.H
+++ b/src/usr/secureboot/trusted/trustedbootCmds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -50,12 +50,6 @@ namespace TRUSTEDBOOT
{
#endif
-enum
-{
- BUFSIZE = 256,
- MAX_TRANSMIT_SIZE = 1024, ///< Maximum send/receive transmit size
-};
-
/**
* @brief Transmit the command to the TPM and perform marshaling
* @param[in/out] io_target Current TPM target structure
@@ -181,6 +175,47 @@ errlHndl_t tpmCmdPcrRead(TpmTarget* io_target,
uint8_t* o_digest,
size_t i_digestSize);
+
+/**
+ * @brief Send the TPM_CC_Create to the TPM
+ * @param[in] i_target the target TPM (must not be nullptr)
+ * @return nullptr if successful; non-nullptr if error
+ *
+ */
+errlHndl_t tpmCmdCreateAttestationKeys(TpmTarget* i_target);
+
+/**
+ * @brief Send the TPM_CC_NV_Read command to the given TPM to read the AK
+ * certificate from its NVRAM
+ * @param[in] i_target the TPM target (must not be nullptr)
+ * @param[out] o_data the pointer to the data contained within NVRAM of the TPM
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t tpmCmdReadAKCertificate(TpmTarget* i_target,
+ AKCertificate_t* o_data);
+
+/**
+ * @brief Send the TPM_CC_Quote command to the given TPM to generate quote
+ * and signature information (returned in o_data)
+ * @param[in] i_target the TPM target (must not be nullptr)
+ * @param[in] i_masterNonce the 32-byte master nonce
+ * @param[out] o_data a pointer to the data structure containing the size of
+ * the quote data from the TPM and the actual data
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t tpmCmdGenerateQuote(TpmTarget* i_target,
+ MasterTpmNonce_t* i_masterNonce,
+ QuoteDataOut* o_data);
+
+/**
+ * @brief Send the TPM2_FlushContext command to the given TPM to remove
+ * transient objects
+ * @param[in] i_target the TPM target (must not be nullptr)
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t tpmCmdFlushContext(TpmTarget* i_target);
+
+
#ifdef __cplusplus
} // end TRUSTEDBOOT namespace
#endif
OpenPOWER on IntegriCloud