diff options
Diffstat (limited to 'src/usr/secureboot')
| -rw-r--r-- | src/usr/secureboot/ext/drtm.C | 8 | ||||
| -rw-r--r-- | src/usr/secureboot/node_comm/node_comm.H | 23 | ||||
| -rw-r--r-- | src/usr/secureboot/node_comm/node_comm_exchange.C | 327 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedbootMsg.H | 6 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 78 | ||||
| -rwxr-xr-x | src/usr/secureboot/trusted/test/tpmLogMgrTest.H | 40 | ||||
| -rwxr-xr-x | src/usr/secureboot/trusted/test/trustedbootTest.H | 4 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/tpmLogMgr.C | 37 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/tpmLogMgr.H | 8 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/trustedTypes.H | 5 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 64 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/trustedboot.H | 3 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/trustedbootCmds.C | 48 | ||||
| -rw-r--r-- | src/usr/secureboot/trusted/trustedbootCmds.H | 9 |
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 |

