summaryrefslogtreecommitdiffstats
path: root/src/usr/secureboot
diff options
context:
space:
mode:
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