summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot
diff options
context:
space:
mode:
authorIlya Smirnov <ismirno@us.ibm.com>2019-01-29 09:54:24 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-02-20 11:38:57 -0600
commit3a6180ba355940c952f332ebd514c8eb15ef7c7a (patch)
treec89a5c02d65ab739065ef0b2369b69c5c3f814e9 /src/usr/secureboot
parent7c42c4cac7170fec81761a8ae35a1e110a38dcc2 (diff)
downloadtalos-hostboot-3a6180ba355940c952f332ebd514c8eb15ef7c7a.tar.gz
talos-hostboot-3a6180ba355940c952f332ebd514c8eb15ef7c7a.zip
Secureboot: Enhanced Multinode Comm: Master Node
This commit introduces the logic to create the master node nodecomm request to the slave nodes and logic to process the responses from the slave nodes. The data from the slave nodes (the slave quote) is hashed and extended into PCR1. The binary quote blob is also included in the TPM log as a log message. Additional changes: the logic to relocate the TPM log to increase its size, and the logic to allow uint8_t* instead of char* as the TPM log message. Change-Id: Ide4465f0d4a91aec815c9db5d765cdbde231dcd3 RTC: 203644 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71407 Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Christopher J. Engel <cjengel@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@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')
-rw-r--r--src/usr/secureboot/ext/drtm.C8
-rw-r--r--src/usr/secureboot/node_comm/node_comm.H23
-rw-r--r--src/usr/secureboot/node_comm/node_comm_exchange.C327
-rw-r--r--src/usr/secureboot/trusted/base/trustedbootMsg.H6
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C78
-rwxr-xr-xsrc/usr/secureboot/trusted/test/tpmLogMgrTest.H40
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H4
-rw-r--r--src/usr/secureboot/trusted/tpmLogMgr.C37
-rw-r--r--src/usr/secureboot/trusted/tpmLogMgr.H8
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.H5
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C64
-rw-r--r--src/usr/secureboot/trusted/trustedboot.H3
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C48
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.H9
14 files changed, 561 insertions, 99 deletions
diff --git a/src/usr/secureboot/ext/drtm.C b/src/usr/secureboot/ext/drtm.C
index 68d59f27e..bec207b7d 100644
--- a/src/usr/secureboot/ext/drtm.C
+++ b/src/usr/secureboot/ext/drtm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -79,7 +79,7 @@ const uint32_t DRTM_RIT_PAYLOAD_PHYS_ADDR_MB = 256-1;
// RIT protection payload
const char DRTM_RIT_PAYLOAD[] = {'D','R','T','M'};
-const char* const DRTM_RIT_LOG_TEXT = "DrtmPayload";
+const uint8_t const DRTM_RIT_LOG_TEXT[] = "DrtmPayload";
#endif
@@ -411,7 +411,9 @@ errlHndl_t validateDrtmPayload()
pError = TRUSTEDBOOT::pcrExtend(TRUSTEDBOOT::PCR_DRTM_17,
TRUSTEDBOOT::EV_COMPACT_HASH,
hash,
- sizeof(SHA512_t),DRTM_RIT_LOG_TEXT);
+ sizeof(SHA512_t),
+ DRTM_RIT_LOG_TEXT,
+ sizeof(DRTM_RIT_LOG_TEXT));
if(pError)
{
SB_ERR("validateDrtmPayload: Failed in pcrExtend() for PCR 17");
diff --git a/src/usr/secureboot/node_comm/node_comm.H b/src/usr/secureboot/node_comm/node_comm.H
index d7b843a3e..e44893683 100644
--- a/src/usr/secureboot/node_comm/node_comm.H
+++ b/src/usr/secureboot/node_comm/node_comm.H
@@ -35,6 +35,8 @@
#include <scom/centaurScomCache.H> // for TRACE_ERR_FMT, TRACE_ERR_ARGS
#include <secureboot/nodecommif.H>
#include "../trusted/trustedboot.H"
+#include <secureboot/trustedbootif.H>
+#include "../trusted/trustedTypes.H"
// ----------------------------------------------
// Defines
@@ -99,6 +101,27 @@ enum node_comm_registers_t : uint64_t
*/
};
+// Each hex number is an encoding of the ascii string
+// corresponding to the name given below.
+typedef enum : uint64_t
+{
+ MSTNOTPM = 0x4d53544e4f54504d,
+ NDNOTPM_ = 0x4e444e4f54504d5f,
+ MASTERQ_ = 0x4d4153545245515f,
+ NODEQUOT = 0x4e4f444551554f54,
+ INVALID_ = 0x494e56414c49445f,
+} NCEyeCatcher_t;
+
+// Enhanced multinode comm master node request blob
+struct _MasterQuoteRequestBlob
+{
+ SECUREBOOT::NODECOMM::NCEyeCatcher_t EyeCatcher; // master node eye catcher
+ TRUSTEDBOOT::MasterTpmNonce_t MasterNonce; //32-byte nonce
+ TRUSTEDBOOT::TPML_PCR_SELECTION PcrSelect; // PCRs to read
+} PACKED;
+typedef struct _MasterQuoteRequestBlob MasterQuoteRequestBlob;
+
+
/**
* @brief Convert Link Mailbox Register Address based on mode (XBUS or ABUS)
*
diff --git a/src/usr/secureboot/node_comm/node_comm_exchange.C b/src/usr/secureboot/node_comm/node_comm_exchange.C
index a7efd6129..eb492a3f4 100644
--- a/src/usr/secureboot/node_comm/node_comm_exchange.C
+++ b/src/usr/secureboot/node_comm/node_comm_exchange.C
@@ -246,11 +246,13 @@ errlHndl_t nodeCommAbusLogNonce(uint64_t & i_nonce)
uint8_t l_digest[sizeof(i_nonce)]={0};
memcpy(l_digest, &i_nonce, sizeof(i_nonce));
+ uint8_t l_logMsg[] = "Node Nonce";
err = TRUSTEDBOOT::pcrExtend(TRUSTEDBOOT::PCR_1,
TRUSTEDBOOT::EV_PLATFORM_CONFIG_FLAGS,
l_digest,
sizeof(uint64_t),
- "Node Nonce");
+ l_logMsg,
+ sizeof(l_logMsg));
if (err)
{
TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommAbusLogNonce: pcrExtend "
@@ -276,12 +278,7 @@ errlHndl_t nodeCommAbusLogNonce(uint64_t & i_nonce)
* the QuoteDataOut structure), the contents of PCRs 0-7, the
* Attestation Key Certificate returned from TPM, the size
* and the contents of the TPM log
- * @param[in] i_masterEyeCatcher the eye catcher from master node that indicates
- * the state of master node's TPM. (If master node's TPM is in bad
- * state, the slave node won't generate the full quote, as remote
- * attestation is not possible)
- * @param[in] i_nonce the 32-byte nonce generated by the master node
- * @param[in] i_pcrSelect the PCR selection structure
+ * @param[in] i_request the master node request structure
* @param[out] o_size the size of the slave quote
* @param[out] o_resp the slave quote in binary format
* @note Assuming CONFIG_TPMDD is compiled in, o_resp is always allocated
@@ -291,9 +288,7 @@ errlHndl_t nodeCommAbusLogNonce(uint64_t & i_nonce)
* indicating that the slave quote is bad.
* @return nullptr on success; non-nullptr on error
*/
-errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatcher_t i_masterEyeCatch,
- const TRUSTEDBOOT::MasterTpmNonce_t* const i_nonce,
- const TRUSTEDBOOT::TPML_PCR_SELECTION* const i_pcrSelect,
+errlHndl_t nodeCommGenSlaveResponseQuote(const MasterQuoteRequestBlob* const i_request,
size_t& o_size,
uint8_t*& o_resp)
{
@@ -326,7 +321,7 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
// policy is off, send back a token indicating that no nodecomm TPM commands
// have been performed (remote attestation is not possible with bad master
// TPM); do not fail the boot.
- if(i_masterEyeCatch == SECUREBOOT::NODECOMM::MSTNOTPM)
+ if(i_request->EyeCatcher == MSTNOTPM)
{
l_errorOccurred = true;
TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: Master indicated an issue with secure nodecomm (master eye catcher is MSTNOTPM)");
@@ -361,10 +356,10 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
// The error condition will be handled below in the if branch that
// checks l_errorOccurred
}
- else if(i_masterEyeCatch != SECUREBOOT::NODECOMM::MASTERQ_)
+ else if(i_request->EyeCatcher != MASTERQ_)
{
l_errorOccurred = true;
- TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: Invalid master eye catcher received: 0x%x", i_masterEyeCatch);
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: Invalid master eye catcher received: 0x%x", i_request->EyeCatcher);
if(l_tpmRequired)
{
/* @
@@ -378,7 +373,7 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MOD_NC_GEN_SLAVE_RESPONSE,
RC_NC_BAD_MASTER_EYE_CATCH,
- i_masterEyeCatch);
+ i_request->EyeCatcher);
// It is unlikely that there is an issue with this node, but collect
// the logs anyway for ease of debug.
l_errl->collectTrace(NODECOMM_TRACE_NAME);
@@ -415,7 +410,8 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
TRUSTEDBOOT::EV_PLATFORM_CONFIG_FLAGS,
l_AKCertHash,
sizeof(l_AKCertHash),
- "AK Certificate Hash"); // @TODO RTC 203644 this should be a full AK certificate in binary
+ l_AKCert.buffer,
+ sizeof(l_AKCert.buffer));
if(l_errl)
{
TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: could not extend AK Certificate hash to TPM");
@@ -427,7 +423,7 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
// Step 3: Generate quote and signature data (presented as binary data in
// the QuoteDataOut structure)
l_errl = TRUSTEDBOOT::generateQuote(l_primaryTpm,
- i_nonce,
+ &i_request->MasterNonce,
&l_quoteData);
if(l_errl)
{
@@ -443,10 +439,11 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
break;
}
- // @TODO RTC 203645 use the i_pcrSelect to read selected PCRs
- // Step 5: Read PCRs 0-7
- uint32_t l_pcrCount = TRUSTEDBOOT::FW_USED_PCR_COUNT;
- TRUSTEDBOOT::TPM_Pcr l_pcrRegs[l_pcrCount] = {
+ // Step 5: Read the selected PCRs
+ // Make sure there is only 1 algo selection
+ assert(i_request->PcrSelect.count == 1, "nodeCommGenSlaveResponseQuote: only 1 hash algo is supported for PCR read");
+ uint32_t l_pcrCount = 0;
+ TRUSTEDBOOT::TPM_Pcr l_pcrRegs[TRUSTEDBOOT::FW_USED_PCR_COUNT] = {
TRUSTEDBOOT::PCR_0,
TRUSTEDBOOT::PCR_1,
TRUSTEDBOOT::PCR_2,
@@ -456,23 +453,34 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
TRUSTEDBOOT::PCR_6,
TRUSTEDBOOT::PCR_7
};
- size_t l_digestSize =
- TRUSTEDBOOT::getDigestSize(TRUSTEDBOOT::TPM_ALG_SHA256);
+ TRUSTEDBOOT::TPM_Alg_Id l_algId = static_cast<TRUSTEDBOOT::TPM_Alg_Id>
+ (i_request->PcrSelect.pcrSelections[0].algorithmId);
+ size_t l_digestSize = TRUSTEDBOOT::getDigestSize(l_algId);
- // An array of PCR Digest structures to hold the contents of PCRs 0-7
- TRUSTEDBOOT::TPM2B_DIGEST l_pcrDigests[l_pcrCount];
+ // An array of PCR Digest structures to hold the contents of the selected
+ // PCRs
+ TRUSTEDBOOT::TPM2B_DIGEST l_pcrDigests[TRUSTEDBOOT::FW_USED_PCR_COUNT] {};
+
+ // Iterate through PCRs that hostboot interacts with (PCR0-7) and see
+ // if any of those were seleceted; read the selected ones
for(const auto l_pcr : l_pcrRegs)
{
- l_pcrDigests[l_pcr].size = l_digestSize;
- l_errl = TRUSTEDBOOT::pcrRead(l_primaryTpm,
+ if((i_request->PcrSelect.pcrSelections[0]
+ .pcrSelect[l_pcr/TRUSTEDBOOT::FW_USED_PCR_COUNT]) &
+ (0x01 << (l_pcr % TRUSTEDBOOT::FW_USED_PCR_COUNT)))
+ {
+ ++l_pcrCount;
+ l_pcrDigests[l_pcr].size = l_digestSize;
+ l_errl = TRUSTEDBOOT::pcrRead(l_primaryTpm,
l_pcr,
- TRUSTEDBOOT::TPM_ALG_SHA256,
+ l_algId,
l_digestSize,
l_pcrDigests[l_pcr].buffer);
- if(l_errl)
- {
- TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: could not read PCR%d", l_pcr);
- break;
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenSlaveResponseQuote: could not read PCR%d", l_pcr);
+ break;
+ }
}
}
if(l_errl)
@@ -507,15 +515,15 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
const uint8_t* l_logPtr =
TRUSTEDBOOT::TpmLogMgr_getLogStartPtr(l_primaryLogMgr);
- SECUREBOOT::NODECOMM::NCEyeCatcher_t l_goodEyeCatch =
- SECUREBOOT::NODECOMM::NODEQUOT;
+ NCEyeCatcher_t l_goodEyeCatch = NODEQUOT;
// Figure out the size of the slave quote
o_size = sizeof(l_goodEyeCatch) +
sizeof(l_nodeId) +
l_quoteData.size +
sizeof(l_pcrCount) +
- sizeof(l_pcrDigests) +
+ // Only include the read PCRs in the slave quote
+ sizeof(TRUSTEDBOOT::TPM2B_DIGEST) * l_pcrCount +
sizeof(l_AKCert) +
sizeof(l_logSize) +
l_logSize;
@@ -538,17 +546,29 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
// The number of PCRs read
memcpy(o_resp + l_currentOffset, &l_pcrCount, sizeof(l_pcrCount));
l_currentOffset += sizeof(l_pcrCount);
- // PCR0-7 contents
- memcpy(o_resp + l_currentOffset,
- reinterpret_cast<uint8_t*>(&l_pcrDigests),
- sizeof(l_pcrDigests));
- l_currentOffset += sizeof(l_pcrDigests);
+ // PCR contents
+ for(const auto l_pcr : l_pcrRegs)
+ {
+ if(l_pcrDigests[l_pcr].size != 0)
+ {
+ // Copy the size of the PCR
+ memcpy(o_resp + l_currentOffset,
+ &l_pcrDigests[l_pcr].size,
+ sizeof(l_pcrDigests[l_pcr].size));
+ l_currentOffset += sizeof(l_pcrDigests[l_pcr].size);
+ // Now the actual data
+ memcpy(o_resp + l_currentOffset,
+ l_pcrDigests[l_pcr].buffer,
+ l_pcrDigests[l_pcr].size);
+ l_currentOffset += l_pcrDigests[l_pcr].size;
+ }
+ }
// AK certificate size
memcpy(o_resp + l_currentOffset, &l_AKCert.size, sizeof(l_AKCert.size));
l_currentOffset += sizeof(l_AKCert.size);
// Actual AK certificate
- memcpy(o_resp + l_currentOffset, l_AKCert.buffer, sizeof(l_AKCert.buffer));
- l_currentOffset += sizeof(l_AKCert.buffer);
+ memcpy(o_resp + l_currentOffset, l_AKCert.buffer, l_AKCert.size);
+ l_currentOffset += l_AKCert.size;
// The length of the TPM log
memcpy(o_resp + l_currentOffset, &l_logSize, sizeof(l_logSize));
l_currentOffset += sizeof(l_logSize);
@@ -567,8 +587,7 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
{
// There was some error; allocate the output buffer just big enough
// for an eye catcher and node ID
- SECUREBOOT::NODECOMM::NCEyeCatcher_t l_badEyeCatcher =
- SECUREBOOT::NODECOMM::NDNOTPM_;
+ NCEyeCatcher_t l_badEyeCatcher = NDNOTPM_;
o_resp = new uint8_t[sizeof(l_badEyeCatcher) + sizeof(l_nodeId)]{};
memcpy(o_resp, &l_badEyeCatcher, sizeof(l_badEyeCatcher));
memcpy(o_resp + sizeof(l_badEyeCatcher), &l_nodeId, sizeof(l_nodeId));
@@ -601,6 +620,203 @@ errlHndl_t nodeCommGenSlaveResponseQuote(const SECUREBOOT::NODECOMM::NCEyeCatche
} //nodeCommGenSlaveResponseQuote
/**
+ * @brief A function to generate a master quote request blob that will be sent
+ * to the slave node(s) as part of the node communication protocol. The
+ * master request consists of an eye catcher, 32-byte TPM-generated
+ * random number, and a PCR selection structure.
+ * @param[out] o_request the output master quote request data structure
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t nodeCommGenMasterRequestQuote(MasterQuoteRequestBlob* const o_request)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ TRACFCOMP(g_trac_nc, ENTER_MRK"nodeCommGenMasterRequestQuote");
+ bool l_tpmRequired = TRUSTEDBOOT::isTpmRequired();
+ do {
+ TARGETING::Target* l_primaryTpm = nullptr;
+ TRUSTEDBOOT::getPrimaryTpm(l_primaryTpm);
+ if(!l_primaryTpm ||
+ !l_primaryTpm->getAttr<TARGETING::ATTR_HWAS_STATE>().functional ||
+ !l_primaryTpm->getAttr<TARGETING::ATTR_HWAS_STATE>().present)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenMasterRequestQuote: primary TPM not found or is not functional");
+
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NC_GEN_MASTER_REQUEST,
+ RC_NC_BAD_MASTER_TPM);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ l_errl->collectTrace(NODECOMM_TRACE_NAME);
+ break;
+ }
+
+ o_request->EyeCatcher = MASTERQ_;
+
+ // Generate the 32-byte nonce for master request
+ l_errl = TRUSTEDBOOT::GetRandom(l_primaryTpm,
+ sizeof(o_request->MasterNonce),
+ o_request->MasterNonce);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommGenMasterRequestQuote: GetRandom failed");
+ break;
+ }
+
+ // Select PCRs (PCR0-7) to include in slave response quote
+ o_request->PcrSelect.count = 1; // One algorithm
+ o_request->PcrSelect.pcrSelections[0].algorithmId =
+ TRUSTEDBOOT::TPM_ALG_SHA256;
+ o_request->PcrSelect.pcrSelections[0].sizeOfSelect =
+ TRUSTEDBOOT::PCR_SELECT_MAX;
+ memset(o_request->PcrSelect.pcrSelections[0].pcrSelect, 0,
+ sizeof(o_request->PcrSelect.pcrSelections[0].pcrSelect));
+
+ TRUSTEDBOOT::TPM_Pcr l_pcrRegs[TRUSTEDBOOT::FW_USED_PCR_COUNT] = {
+ TRUSTEDBOOT::PCR_0,
+ TRUSTEDBOOT::PCR_1,
+ TRUSTEDBOOT::PCR_2,
+ TRUSTEDBOOT::PCR_3,
+ TRUSTEDBOOT::PCR_4,
+ TRUSTEDBOOT::PCR_5,
+ TRUSTEDBOOT::PCR_6,
+ TRUSTEDBOOT::PCR_7
+ };
+ for(const auto l_pcr : l_pcrRegs)
+ {
+ o_request->PcrSelect.pcrSelections[0]
+ .pcrSelect[l_pcr/TRUSTEDBOOT::FW_USED_PCR_COUNT] |=
+ 0x01 << (l_pcr % TRUSTEDBOOT::FW_USED_PCR_COUNT);
+ }
+
+ } while(0);
+
+ if(l_errl)
+ {
+ // Error occurred. Tell the slave that the master TPM is unavailable and
+ // poison the TPMs on master node.
+ o_request->EyeCatcher = MSTNOTPM;
+ errlHndl_t l_poisonTpmErr = TRUSTEDBOOT::poisonAllTpms();
+ if(l_poisonTpmErr)
+ {
+ if(l_errl)
+ {
+ l_poisonTpmErr->plid(l_errl->plid());
+ }
+ errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
+ }
+
+ if(!l_tpmRequired)
+ {
+ // TPM is not required, so no need to propagate the error up and
+ // fail the boot.
+ errlCommit(l_errl, SECURE_COMP_ID);
+ }
+ }
+
+ TRACFCOMP(g_trac_nc, EXIT_MRK"nodeCommGenMasterRequestQuote: " TRACE_ERR_FMT, TRACE_ERR_ARGS(l_errl));
+#endif
+ return l_errl;
+} // nodeCommGenMasterRequestQuote
+
+/**
+ * @brief A function to process the response of one of the slave nodes
+ * @param[in] i_slaveQuote the quote received from a slave node in binary format
+ * @param[in] i_slaveQuoteSize the size of the slave quote (in bytes)
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t nodeCommProcessSlaveQuote(uint8_t* const i_slaveQuote,
+ const size_t i_slaveQuoteSize)
+{
+ errlHndl_t l_errl = nullptr;
+#ifdef CONFIG_TPMDD
+ TRACFCOMP(g_trac_nc, ENTER_MRK"nodeCommProcessSlaveQuote");
+ bool l_tpmRequired = TRUSTEDBOOT::isTpmRequired();
+ bool l_errorOccurred = false;
+
+ do {
+ NCEyeCatcher_t* l_eyeCatcher =
+ reinterpret_cast<NCEyeCatcher_t*>(i_slaveQuote);
+ uint32_t* l_slaveNodeId = reinterpret_cast<uint32_t*>(i_slaveQuote +
+ sizeof(l_eyeCatcher));
+ if(*l_eyeCatcher == NDNOTPM_)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommProcessSlaveQuote: Slave node %d indicated that it could not complete the slave quote generation process", *l_slaveNodeId);
+ l_errorOccurred = true;
+ if(l_tpmRequired)
+ {
+ // Slave sent bad data and TPM is required - return an error and
+ // the IPL should be terminated
+
+ /* @
+ * @errortype
+ * @reasoncode RC_NC_BAD_SLAVE_QUOTE
+ * @moduleid MOD_NC_PROCESS_SLAVE_QUOTE
+ * @userdata1 Slave node where the quote came from
+ * @devdesc One of the slave nodes indicated that there was
+ * an issue with its TPM or quote generation process
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_NC_PROCESS_SLAVE_QUOTE,
+ RC_NC_BAD_SLAVE_QUOTE,
+ *l_slaveNodeId,
+ 0);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(TRBOOT_COMP_NAME);
+ l_errl->collectTrace(NODECOMM_TRACE_NAME);
+ }
+ else
+ {
+ // @TODO RTC 203645 need to notify HDAT to turn off trustedboot flag
+ // in RUNTIME::IPLPARMS_SYSTEM
+ }
+ break;
+ }
+
+ // Extend the hash of the slave quote to PCR 1, and include the whole quote
+ // in binary form as the message in the TPM log
+ SHA512_t l_quoteHash = {0};
+ hashBlob(i_slaveQuote, i_slaveQuoteSize, l_quoteHash);
+ l_errl = TRUSTEDBOOT::pcrExtend(TRUSTEDBOOT::PCR_1,
+ TRUSTEDBOOT::EV_PLATFORM_CONFIG_FLAGS,
+ l_quoteHash,
+ sizeof(l_quoteHash),
+ i_slaveQuote,
+ i_slaveQuoteSize);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_nc, ERR_MRK"nodeCommProcessSlaveQuote: could not extend slave response to PCR 1");
+ break;
+ }
+
+ } while(0);
+
+ if(l_errl || l_errorOccurred)
+ {
+ errlHndl_t l_poisonTpmErr = TRUSTEDBOOT::poisonAllTpms();
+ if(l_poisonTpmErr)
+ {
+ if(l_errl)
+ {
+ l_poisonTpmErr->plid(l_errl->plid());
+ }
+ errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
+ }
+
+ if(!TRUSTEDBOOT::isTpmRequired())
+ {
+ // TPM is not required - do not propagate the error
+ errlCommit(l_errl, SECURE_COMP_ID);
+ }
+ }
+
+ TRACFCOMP(g_trac_nc, EXIT_MRK"nodeCommProcessSlaveQuote: " TRACE_ERR_FMT, TRACE_ERR_ARGS(l_errl));
+#endif
+ return l_errl;
+} // nodeCommProcessSlaveQuote
+
+/**
* @brief This function runs the procedure for the master processor on the
* master node to send and receive messages over the ABUS to the
* master processors on the slave nodes
@@ -630,6 +846,30 @@ errlHndl_t nodeCommAbusExchangeMaster(const master_proc_info_t & i_mProcInfo,
do
{
+ // The slave quote that is returned by the slave nodes as part of the node
+ // comm protocol is too big to be placed in the TPM's log without moving the
+ // log to a new memory location, so before processing the slave quote, we
+ // need to send a message to the TPM queue to expand the log. We need to
+ // expand logs on all TPMs, since logging and PCR extends are mirrorred into
+ // all TPMs/logs on the node.
+ TARGETING::TargetHandleList l_tpms;
+ TRUSTEDBOOT::getTPMs(l_tpms);
+ for(const auto& l_tpm : l_tpms)
+ {
+ err = TRUSTEDBOOT::expandTpmLog(l_tpm);
+ if(err)
+ {
+ TRACFCOMP(g_trac_nc,ERR_MRK"nodeCommAbusExchangeMaster: could not expand the TPM log for TPM HUID 0x%x", TARGETING::get_huid(l_tpm));
+ break;
+ }
+ }
+
+ if(err)
+ {
+ break;
+ }
+
+
for ( auto const l_obus : i_obus_instances)
{
uint8_t my_linkId = 0;
@@ -667,6 +907,7 @@ errlHndl_t nodeCommAbusExchangeMaster(const master_proc_info_t & i_mProcInfo,
TRACE_ERR_ARGS(err));
break;
}
+
// Set the send and expected receive LinkIds in the nonce
msg_data.origin_linkId = my_linkId;
msg_data.receiver_linkId = expected_peer_linkId;
diff --git a/src/usr/secureboot/trusted/base/trustedbootMsg.H b/src/usr/secureboot/trusted/base/trustedbootMsg.H
index 929233111..40e1e53ec 100644
--- a/src/usr/secureboot/trusted/base/trustedbootMsg.H
+++ b/src/usr/secureboot/trusted/base/trustedbootMsg.H
@@ -63,7 +63,8 @@ namespace TRUSTEDBOOT
MSG_TYPE_GEN_QUOTE,
MSG_TYPE_FLUSH_CONTEXT,
MSG_TYPE_PCR_READ,
- MSG_TYPE_LAST = MSG_TYPE_PCR_READ,
+ MSG_TYPE_EXPAND_TPM_LOG,
+ MSG_TYPE_LAST = MSG_TYPE_EXPAND_TPM_LOG,
};
/// PCREXTEND message data
@@ -74,7 +75,8 @@ namespace TRUSTEDBOOT
EventTypes mEventType;
size_t mDigestSize;
uint8_t mDigest[TPM_ALG_SHA256_SIZE];
- char mLogMsg[MAX_TPM_LOG_MSG];
+ uint8_t mLogMsg[MAX_TPM_LOG_MSG];
+ size_t mLogMsgSize;
const TpmTarget* mSingleTpm;
bool mMirrorToLog;
};
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index e0170b164..9e78e08f5 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -199,7 +199,8 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
EventTypes i_eventType,
const uint8_t* i_digest,
size_t i_digestSize,
- const char* i_logMsg,
+ const uint8_t* i_logMsg,
+ const size_t i_logMsgSize,
bool i_sendAsync,
const TpmTarget* i_pTpm,
const bool i_mirrorToLog)
@@ -210,8 +211,13 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
TRACDCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtend()" );
TRACUCOMP( g_trac_trustedboot,
- ENTER_MRK"pcrExtend() pcr=%d msg='%s'",
- i_pcr, i_logMsg? i_logMsg: "(null)");
+ ENTER_MRK"pcrExtend() pcr=%d",
+ i_pcr);
+ if(i_logMsg)
+ {
+ TRACUBIN(g_trac_trustedboot, "TPM log msg", i_logMsg, i_logMsgSize);
+ }
+
TRACUBIN(g_trac_trustedboot, "pcrExtend() digest:", i_digest, i_digestSize);
// msgData will be freed when message is freed
@@ -233,10 +239,10 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
if (i_logMsg)
{
memcpy(msgData->mLogMsg, i_logMsg,
- (strlen(i_logMsg) < sizeof(msgData->mLogMsg) ? strlen(i_logMsg) :
- sizeof(msgData->mLogMsg)-1) // Leave room for NULL termination
- );
+ (i_logMsgSize < sizeof(msgData->mLogMsg) ?
+ i_logMsgSize : sizeof(msgData->mLogMsg)));
}
+ msgData->mLogMsgSize = i_logMsgSize;
if (!i_sendAsync)
{
@@ -369,7 +375,8 @@ errlHndl_t extendPnorSectionHash(
pnorHashEventType,
reinterpret_cast<const uint8_t*>(i_conHdr.payloadTextHash()),
sizeof(SHA512_t),
- sectionInfo.name);
+ reinterpret_cast<const uint8_t*>(sectionInfo.name),
+ strlen(sectionInfo.name) + 1);
if (pError)
{
TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
@@ -383,7 +390,8 @@ errlHndl_t extendPnorSectionHash(
swKeyHashEventType,
reinterpret_cast<const uint8_t*>(i_conHdr.swKeyHash()),
sizeof(SHA512_t),
- swKeyMsg);
+ reinterpret_cast<const uint8_t*>(swKeyMsg),
+ strlen(swKeyMsg) + 1);
if (pError)
{
TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
@@ -401,7 +409,8 @@ errlHndl_t extendPnorSectionHash(
pnorHashEventType,
hash,
sizeof(SHA512_t),
- sectionInfo.name);
+ reinterpret_cast<const uint8_t*>(sectionInfo.name),
+ strlen(sectionInfo.name) + 1);
if (pError)
{
TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
@@ -1120,4 +1129,55 @@ errlHndl_t pcrRead(TpmTarget* i_target,
return l_errl;
}
+errlHndl_t expandTpmLog(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_EXPAND_TPM_LOG,
+ sizeof(*l_data),
+ reinterpret_cast<uint8_t*>(l_data),
+ MSG_MODE_SYNC);
+ assert(l_msg, "expandTpmLog: 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_EXPAND_TPM_LOG
+ * @reasoncode RC_SENDRECV_FAIL
+ * @userdata1 rc from msg_sendrecv
+ * @userdata2 TPM HUID
+ * @devdesc msg_sendrecv failed for expandTpmLog
+ * @custdesc trustedboot failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_EXPAND_TPM_LOG,
+ 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/tpmLogMgrTest.H b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H
index 0e67056a8..aa0aa304b 100755
--- a/src/usr/secureboot/trusted/test/tpmLogMgrTest.H
+++ b/src/usr/secureboot/trusted/test/tpmLogMgrTest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -198,7 +198,8 @@ class TPMLogMgrTest: public CxxTest::TestSuite
* @brief Add generic test event to log and return the event added
*/
TCG_PCR_EVENT2 addTestLogEvent(TpmLogMgr& i_logMgr,
- const char* i_logMsg)
+ const uint8_t* i_logMsg,
+ size_t i_logMsgSize)
{
// Set components of TCG_PCR_EVENT2
TPM_Pcr pcr = PCR_0;
@@ -215,14 +216,18 @@ class TPMLogMgrTest: public CxxTest::TestSuite
pcr, EV_NO_ACTION, algId,
digest, digestSize,
TPM_ALG_SHA1, digest,
- digestSize, i_logMsg);
+ digestSize, i_logMsg,
+ i_logMsgSize);
// Add event to log
errlHndl_t err = TpmLogMgr_addEvent(&i_logMgr, &eventLog);
if (err)
{
- TS_FAIL("addTestLogEvent - Failed to addEvent with message = %s",
- i_logMsg);
+ TS_FAIL("addTestLogEvent - Failed to addEvent with the following message");
+ TRACFBIN(g_trac_trustedboot,
+ "TPM log message",
+ i_logMsg,
+ i_logMsgSize);
errlCommit( err, TRBOOT_COMP_ID );
delete err;
err = NULL;
@@ -244,8 +249,10 @@ class TPMLogMgrTest: public CxxTest::TestSuite
getTestLogMgr(&logMgr);
// Add event to log
- const char* logMsg = "testTpmLogReadSingleEntry";
- TCG_PCR_EVENT2 eventLog = addTestLogEvent(logMgr, logMsg);
+ uint8_t logMsg[] = "testTpmLogReadSingleEntry";
+ TCG_PCR_EVENT2 eventLog = addTestLogEvent(logMgr,
+ logMsg,
+ sizeof(logMsg));
// Retrive event from log
TCG_PCR_EVENT2 resultEventLog;
@@ -330,8 +337,8 @@ class TPMLogMgrTest: public CxxTest::TestSuite
getTestLogMgr(&logMgr);
// Add event to log
- const char* logMsg = "testTpmLogReadPastValidLog";
- addTestLogEvent(logMgr, logMsg);
+ uint8_t logMsg[] = "testTpmLogReadPastValidLog";
+ addTestLogEvent(logMgr, logMsg, sizeof(logMsg));
// Retrive event from log
TCG_PCR_EVENT2 resultEventLog;
@@ -389,9 +396,11 @@ class TPMLogMgrTest: public CxxTest::TestSuite
break;
}
+ uint8_t logMsg[] = "CalcLog11";
// Add an event to log
TCG_PCR_EVENT2 eventLog = addTestLogEvent(logMgr,
- "CalcLog11");
+ logMsg,
+ sizeof(logMsg));
if (TpmLogMgr_calcLogSize(&logMgr) !=
TpmLogMgr_getLogSize(&logMgr) ||
((firstEventSize +
@@ -405,11 +414,13 @@ class TPMLogMgrTest: public CxxTest::TestSuite
break;
}
+ uint8_t logMsg1[] = "CalcLog3434";
// Add more events to log
for (int idx = 0; idx < 10; idx ++)
{
eventLog = addTestLogEvent(logMgr,
- "CalcLog3434");
+ logMsg1,
+ sizeof(logMsg1));
if (TpmLogMgr_calcLogSize(&logMgr) !=
TpmLogMgr_getLogSize(&logMgr))
{
@@ -460,11 +471,13 @@ class TPMLogMgrTest: public CxxTest::TestSuite
}
+ uint8_t logMsg[] = "CalcLog3434";
// Add more events to log
for (int idx = 0; idx < 10; idx ++)
{
eventLog = addTestLogEvent(logMgr,
- "CalcLog3434");
+ logMsg,
+ sizeof(logMsg));
}
err = TpmLogMgr_initializeUsingExistingLog(&cloneMgr,
@@ -484,8 +497,9 @@ class TPMLogMgrTest: public CxxTest::TestSuite
break;
}
+ uint8_t logMsg1[] = "Clone123 23434";
// Now try adding an event to the clone logMgr
- eventLog = addTestLogEvent(cloneMgr, "Clone123 23434");
+ eventLog = addTestLogEvent(cloneMgr, logMsg1, sizeof(logMsg1));
if (TpmLogMgr_getLogSize(&logMgr) ==
TpmLogMgr_getLogSize(&cloneMgr))
{
diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H
index 8c1655dd8..cbf221e57 100755
--- a/src/usr/secureboot/trusted/test/trustedbootTest.H
+++ b/src/usr/secureboot/trusted/test/trustedbootTest.H
@@ -792,6 +792,7 @@ class TrustedBootTest: public CxxTest::TestSuite
for (size_t i = 0; i < EXTEND_PCR_TESTS; ++i) {
+ uint8_t l_logMsg[] = "testExtendPCR: test";
num_ops++;
pcrExtendSingleTpm(pTpm,
PCR_DEBUG,
@@ -799,7 +800,8 @@ class TrustedBootTest: public CxxTest::TestSuite
TPM_ALG_SHA256,
digest,
TPM_ALG_SHA256_SIZE,
- "testExtendPCR: test");
+ l_logMsg,
+ sizeof(l_logMsg));
auto hwasState = pTpm->getAttr<TARGETING::ATTR_HWAS_STATE>();
if(!hwasState.functional)
diff --git a/src/usr/secureboot/trusted/tpmLogMgr.C b/src/usr/secureboot/trusted/tpmLogMgr.C
index 855d02b5a..3c91ce9e6 100644
--- a/src/usr/secureboot/trusted/tpmLogMgr.C
+++ b/src/usr/secureboot/trusted/tpmLogMgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -465,7 +465,8 @@ namespace TRUSTEDBOOT
TPM_Alg_Id i_algId_2,
const uint8_t* i_digest_2,
size_t i_digestSize_2,
- const char* i_logMsg)
+ const uint8_t* i_logMsg,
+ const size_t i_logMsgSize)
{
TCG_PCR_EVENT2 eventLog;
size_t fullDigestSize_1 = 0;
@@ -499,12 +500,11 @@ namespace TRUSTEDBOOT
i_digestSize_2 : fullDigestSize_2));
}
// Event field data
- eventLog.event.eventSize = strlen(i_logMsg);
+ eventLog.event.eventSize = i_logMsgSize;
memset(eventLog.event.event, 0, sizeof(eventLog.event.event));
memcpy(eventLog.event.event, i_logMsg,
- (strlen(i_logMsg) > MAX_TPM_LOG_MSG ?
- MAX_TPM_LOG_MSG - 1 // Leave room for NULL termination
- : strlen(i_logMsg)) );
+ (i_logMsgSize > MAX_TPM_LOG_MSG ?
+ MAX_TPM_LOG_MSG : i_logMsgSize));
return eventLog;
}
@@ -583,17 +583,28 @@ namespace TRUSTEDBOOT
i_val->logSize, i_maxSize);
assert(i_newLog != NULL, "Bug! Log start address is nullptr");
- assert(i_val->eventLogInMem == NULL,
- "relocateTpmLog can only be called once");
assert(i_val->logSize < i_maxSize,
"Logsize is greater than maxsize");
- // Point logMgr to new location
- i_val->eventLogInMem = i_newLog;
+ if(i_val->eventLogInMem)
+ {
+ // The log had been expanded previously. Need to copy over the log
+ // memory to the new location and delete the pointer before
+ // reassigning
+ memcpy(i_newLog, i_val->eventLogInMem, i_val->logSize);
+ delete[](i_val->eventLogInMem);
+ i_val->eventLogInMem = i_newLog;
+ }
+ else
+ {
+ // Point logMgr to new location
+ i_val->eventLogInMem = i_newLog;
+
+ // Copy log into new location
+ memset(i_val->eventLogInMem, 0, i_maxSize);
+ memcpy(i_val->eventLogInMem, i_val->eventLog, i_val->logSize);
+ }
- // Copy log into new location
- memset(i_val->eventLogInMem, 0, i_maxSize);
- memcpy(i_val->eventLogInMem, i_val->eventLog, i_val->logSize);
i_val->newEventPtr = i_val->eventLogInMem + i_val->logSize;
i_val->logMaxSize = i_maxSize;
diff --git a/src/usr/secureboot/trusted/tpmLogMgr.H b/src/usr/secureboot/trusted/tpmLogMgr.H
index 58d0cd7a0..67c70d463 100644
--- a/src/usr/secureboot/trusted/tpmLogMgr.H
+++ b/src/usr/secureboot/trusted/tpmLogMgr.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -222,7 +222,8 @@ namespace TRUSTEDBOOT
* @param[in] i_algId_2 Algorithm to use
* @param[in] i_digest_2 Digest value to write to PCR, NULL if not used
* @param[in] i_digestSize_2 Byte size of i_digest array
- * @param[in] i_logMsg Null terminated Log message
+ * @param[in] i_logMsg log message in binary form
+ * @param[in] i_logMsgSize the size of log message in bytes
*
* @return TCG_PCR_EVENT2 PCR event log
*/
@@ -234,7 +235,8 @@ namespace TRUSTEDBOOT
TPM_Alg_Id i_algId_2,
const uint8_t* i_digest_2,
size_t i_digestSize_2,
- const char* i_logMsg);
+ const uint8_t* i_logMsg,
+ size_t i_logMsgSize);
/**
* @brief Dump contents of log to a trace
diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H
index ae3f3e233..fee966520 100644
--- a/src/usr/secureboot/trusted/trustedTypes.H
+++ b/src/usr/secureboot/trusted/trustedTypes.H
@@ -47,6 +47,8 @@
#define PACKED __attribute__((__packed__))
#endif
+#include <limits.h>
+
#ifdef __cplusplus
namespace TRUSTEDBOOT
{
@@ -69,7 +71,7 @@ namespace TRUSTEDBOOT
/// Common static values
enum
{
- MAX_TPM_LOG_MSG = 128, ///< Maximum log message size
+ MAX_TPM_LOG_MSG = PAGESIZE, ///< Maximum log message size
HASH_COUNT = 2, ///< Maximum # of digests
@@ -568,6 +570,7 @@ namespace TRUSTEDBOOT
struct _TPM2_NVReadOut
{
TPM2_BaseOut base;
+ uint32_t authSessionSize;
TPM2B_MAX_NV_BUFFER data;
} PACKED;
typedef struct _TPM2_NVReadOut TPM2_NVReadOut;
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index 28521dc7b..1237fe3b8 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -73,6 +73,7 @@
#include <util/misc.H>
#include <hwas/common/hwasCommon.H>
+
namespace TRUSTEDBOOT
{
@@ -738,9 +739,10 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm)
l_securitySwitchValue);
// Extend to TPM - PCR_1
memcpy(l_digest, &l_securitySwitchValue, sizeof(l_securitySwitchValue));
+ uint8_t l_sswitchesLogMsg[] = "Security Switches";
l_err = pcrExtend(PCR_1, EV_PLATFORM_CONFIG_FLAGS,
l_digest, sizeof(l_securitySwitchValue),
- "Security Switches");
+ l_sswitchesLogMsg, sizeof(l_sswitchesLogMsg));
if (l_err)
{
break;
@@ -760,8 +762,10 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm)
TRACDCOMP(g_trac_trustedboot, "PVR of chip = 0x%08X", l_pvr);
// Extend to TPM - PCR_1
memcpy(l_digest, &l_pvr, sizeof(l_pvr));
+ uint8_t l_pvrLogMsg[] = "PVR of Chip";
l_err = pcrExtend(PCR_1, EV_PLATFORM_CONFIG_FLAGS,
- l_digest, sizeof(l_pvr),"PVR of Chip");
+ l_digest, sizeof(l_pvr), l_pvrLogMsg,
+ sizeof(l_pvrLogMsg));
if (l_err)
{
break;
@@ -782,10 +786,12 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm)
const TPM_Pcr l_pcrs[] = {PCR_1,PCR_4,PCR_5,PCR_6};
for (size_t i = 0; i < (sizeof(l_pcrs)/sizeof(TPM_Pcr)) ; ++i)
{
+ uint8_t l_nodeIdLogMsg[] = "Node id";
l_err = pcrExtend(l_pcrs[i],
(l_pcrs[i] == PCR_1 ?
EV_PLATFORM_CONFIG_FLAGS : EV_COMPACT_HASH),
- l_digest, sizeof(l_nodeid),"Node id");
+ l_digest, sizeof(l_nodeid), l_nodeIdLogMsg,
+ sizeof(l_nodeIdLogMsg));
if (l_err)
{
break;
@@ -800,9 +806,11 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm)
memset(l_digest, 0, sizeof(uint64_t));
bool l_tpmRequired = isTpmRequired();
l_digest[0] = static_cast<uint8_t>(l_tpmRequired);
+ uint8_t l_tpmRequiredLogMsg[] = "Tpm Required";
l_err = pcrExtend(PCR_1, EV_PLATFORM_CONFIG_FLAGS,
l_digest, sizeof(l_tpmRequired),
- "Tpm Required");
+ l_tpmRequiredLogMsg,
+ sizeof(l_tpmRequiredLogMsg));
if (l_err)
{
break;
@@ -811,9 +819,11 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget* const i_pTpm)
// HW Key Hash
SHA512_t l_hw_key_hash;
SECUREBOOT::getHwKeyHash(l_hw_key_hash);
+ uint8_t l_hwKeyHashLogMsg[] = "HW KEY HASH";
l_err = pcrExtend(PCR_1, EV_PLATFORM_CONFIG_FLAGS,
l_hw_key_hash,
- sizeof(SHA512_t),"HW KEY HASH");
+ sizeof(SHA512_t),l_hwKeyHashLogMsg,
+ sizeof(l_hwKeyHashLogMsg));
if (l_err)
{
break;
@@ -830,7 +840,8 @@ void pcrExtendSingleTpm(TpmTarget* const i_pTpm,
TPM_Alg_Id i_algId,
const uint8_t* i_digest,
size_t i_digestSize,
- const char* i_logMsg)
+ const uint8_t* i_logMsg,
+ const size_t i_logMsgSize)
{
assert(i_pTpm != nullptr,"pcrExtendSingleTpm: BUG! i_pTpm was nullptr");
assert(i_pTpm->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_TPM,
@@ -882,7 +893,8 @@ void pcrExtendSingleTpm(TpmTarget* const i_pTpm,
TPM_ALG_SHA1,
i_digest,
i_digestSize,
- i_logMsg);
+ i_logMsg,
+ i_logMsgSize);
if(useStaticLog)
{
auto * const pTpmLogMgr = getTpmLogMgr(i_pTpm);
@@ -949,7 +961,7 @@ void pcrExtendSeparator(TpmTarget* const i_pTpm)
0xA6, 0xA9, 0xF7, 0x60, 0x79, 0xE4, 0x8B, 0xF0,
0x90, 0xAC, 0xB7, 0xE8, 0x36, 0x7B, 0xFD, 0x0E};
// The event message is 0xFFFFFFFF
- const char logMsg[] = { 0xFF, 0xFF, 0xFF, 0xFF, '\0'};
+ const uint8_t logMsg[] = { 0xFF, 0xFF, 0xFF, 0xFF };
memset(&eventLog, 0, sizeof(eventLog));
do
@@ -995,7 +1007,8 @@ void pcrExtendSeparator(TpmTarget* const i_pTpm)
TPM_ALG_SHA256,
sha256_digest,
sizeof(sha256_digest),
- logMsg);
+ logMsg,
+ sizeof(logMsg));
if(useStaticLog)
{
@@ -1595,6 +1608,26 @@ errlHndl_t doPcrRead(TpmTarget* i_target,
return l_errl;
}
+errlHndl_t doExpandTpmLog(TpmTarget* i_target)
+{
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ l_errl = validateTpmHandle(i_target);
+ if(l_errl)
+ {
+ break;
+ }
+
+ l_errl = tpmCmdExpandTpmLog(i_target);
+ if(l_errl)
+ {
+ break;
+ }
+ } while(0);
+ return l_errl;
+}
+
void* tpmDaemon(void* unused)
{
bool shutdownPending = false;
@@ -1671,7 +1704,9 @@ void* tpmDaemon(void* unused)
msgData->mDigest,
msgData->mDigestSize,
msgData->mMirrorToLog? msgData->mLogMsg:
- nullptr);
+ nullptr,
+ msgData->mMirrorToLog? msgData->mLogMsgSize:
+ 0);
}
// Lastly make sure we are in a state
@@ -1856,6 +1891,14 @@ void* tpmDaemon(void* unused)
l_data->digest);
}
break;
+ case TRUSTEDBOOT::MSG_TYPE_EXPAND_TPM_LOG:
+ {
+ tb_msg = static_cast<TRUSTEDBOOT::Message*>(msg->extra_data);
+ TpmTargetData* l_data =
+ reinterpret_cast<TpmTargetData*>(tb_msg->iv_data);
+ tb_msg->iv_errl = doExpandTpmLog(l_data->tpm);
+ }
+ break;
default:
assert(false, "Invalid msg command");
@@ -2242,6 +2285,7 @@ errlHndl_t poisonTpm(const TpmTarget* i_pTpm)
reinterpret_cast<sha2_byte*>(&l_randNum),
sizeof(l_randNum),
nullptr, // log not needed for poison operation
+ 0, // log size is 0
false, // call synchronously to daemon
i_pTpm, // only extend to pcr banks for this TPM
false); // don't add PCR measurement to the log
diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H
index 53ddb40fc..6314a8733 100644
--- a/src/usr/secureboot/trusted/trustedboot.H
+++ b/src/usr/secureboot/trusted/trustedboot.H
@@ -160,7 +160,8 @@ void pcrExtendSingleTpm(TpmTarget* i_pTpm,
TPM_Alg_Id i_algId,
const uint8_t* i_digest,
size_t i_digestSize,
- const char* i_logMsg);
+ const uint8_t* i_logMsg,
+ size_t i_logMsgSize);
/**
* @brief Extend a separator into a TPM and log
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
index c989de719..12ce871b6 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.C
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -49,6 +49,7 @@
#include "trustedboot.H"
#include "trustedTypes.H"
#include <secureboot/trustedbootif.H>
+#include "tpmLogMgr.H"
#ifdef CONFIG_DRTM
#include <secureboot/drtm.H>
@@ -411,6 +412,7 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
reinterpret_cast<TPM2_NVReadOut*>(o_outBuf);
TPM2_NVReadOut* l_tpmRespData =
reinterpret_cast<TPM2_NVReadOut*>(i_respBuf);
+ l_respPtr->authSessionSize = l_tpmRespData->authSessionSize;
memcpy(reinterpret_cast<uint8_t*>(&l_tpmRespData->data),
reinterpret_cast<uint8_t*>(&l_respPtr->data),
sizeof(l_tpmRespData->data));
@@ -1596,6 +1598,52 @@ errlHndl_t tpmCmdFlushContext(TpmTarget* i_target)
return l_errl;
}
+errlHndl_t tpmCmdExpandTpmLog(TpmTarget* i_target)
+{
+ TRACFCOMP(g_trac_trustedboot, ENTER_MRK"tpmCmdExpandTpmLog()");
+ errlHndl_t l_errl = nullptr;
+
+ do {
+ auto l_tpmLogMgr = getTpmLogMgr(i_target);
+ if(!l_tpmLogMgr)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"tpmCmdExpandTpmLog: could not fetch TPM log manager for TPM HUID 0x%x", TARGETING::get_huid(i_target));
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @reasoncode RC_NO_TPM_LOG_MGR
+ * @moduleid MOD_TPM_CMD_EXPAND_TPM_LOG
+ * @userdata1 TPM HUID
+ * @devdesc Could not fetch the TPM log manager
+ * @custdesc trustedboot failure
+ */
+ l_errl = tpmCreateErrorLog(MOD_TPM_CMD_EXPAND_TPM_LOG,
+ RC_NO_TPM_LOG_MGR,
+ TARGETING::get_huid(i_target),
+ 0);
+ break;
+ }
+
+ mutex_lock(&l_tpmLogMgr->logMutex);
+
+ assert(l_tpmLogMgr->eventLogInMem == nullptr, "tpmCmdExpandTpmLog: the TPM log manager has already been moved/expanded");
+ l_tpmLogMgr->eventLogInMem = new uint8_t[TPMLOG_DEVTREE_SIZE]();
+ l_tpmLogMgr->logMaxSize = TPMLOG_DEVTREE_SIZE;
+
+ memcpy(l_tpmLogMgr->eventLogInMem,
+ l_tpmLogMgr->eventLog,
+ l_tpmLogMgr->logSize);
+
+ l_tpmLogMgr->newEventPtr = l_tpmLogMgr->eventLogInMem +l_tpmLogMgr->logSize;
+
+ // Remove the old log
+ memset(l_tpmLogMgr->eventLog, 0, l_tpmLogMgr->logSize);
+
+ mutex_unlock(&l_tpmLogMgr->logMutex);
+ } while(0);
+ TRACFCOMP(g_trac_trustedboot, EXIT_MRK"tpmCmdExpandTpmLog()");
+ return l_errl;
+}
+
#ifdef __cplusplus
} // end TRUSTEDBOOT
#endif
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.H b/src/usr/secureboot/trusted/trustedbootCmds.H
index 571b5224c..57b3e519c 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.H
+++ b/src/usr/secureboot/trusted/trustedbootCmds.H
@@ -214,6 +214,15 @@ errlHndl_t tpmCmdGenerateQuote(TpmTarget* i_target,
*/
errlHndl_t tpmCmdFlushContext(TpmTarget* i_target);
+/**
+ * @brief Send the command to the given TPM to increase its TPM log size.
+ * The new TPM log is allocated on the heap, and the caller is
+ * responsible for cleaning it up.
+ * @param[in] i_target the TPM target (must not be nullptr)
+ * @return nullptr on success; non-nullptr on error
+ */
+errlHndl_t tpmCmdExpandTpmLog(TpmTarget* i_target);
+
#ifdef __cplusplus
} // end TRUSTEDBOOT namespace
OpenPOWER on IntegriCloud