summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/trusted
diff options
context:
space:
mode:
authorIlya Smirnov <ismirno@us.ibm.com>2018-12-06 15:22:10 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-01-18 16:44:58 -0600
commit868b68df85eb7aeed7eba3392303fa3be854e2a6 (patch)
treeea6ef1afe17ebc0c39baa4ad0e926be77f36e501 /src/usr/secureboot/trusted
parent6a5388bbc8b066a9547e1e1268e8c3a7e9f33291 (diff)
downloadtalos-hostboot-868b68df85eb7aeed7eba3392303fa3be854e2a6.tar.gz
talos-hostboot-868b68df85eb7aeed7eba3392303fa3be854e2a6.zip
Secureboot: Add New TPM Commands For Nodecomm
This commit adds four new TPM commands, and APIs thereto, for enhanced secure multinode communication protocol. The TPM commands are the base for the new protocol and will be used as part of it. Change-Id: I080ff87cd6001b5d2e13ae350a379cbc2c92bfcf RTC: 202364 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69725 Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
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