summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot/node_comm
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/node_comm
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/node_comm')
-rw-r--r--src/usr/secureboot/node_comm/node_comm.H23
-rw-r--r--src/usr/secureboot/node_comm/node_comm_exchange.C327
2 files changed, 307 insertions, 43 deletions
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;
OpenPOWER on IntegriCloud