/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/secureboot/trusted/base/trustedboot_base.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ /** * @file trustedboot_base.C * * @brief Trusted boot base interfaces * This file is compiled in regardless of CONFIG_TPMDD */ // ---------------------------------------------- // Includes // ---------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../trustedboot.H" #include "../trustedbootCmds.H" #include "../trustedbootUtils.H" #include "../../pnor/pnor_utils.H" #include "trustedbootMsg.H" #include "../tpmLogMgr.H" #include // ---------------------------------------------- // Trace definitions // ---------------------------------------------- trace_desc_t* g_trac_trustedboot = nullptr; TRAC_INIT( & g_trac_trustedboot, TRBOOT_COMP_NAME, KILOBYTE ); namespace TRUSTEDBOOT { // Const string to append to PCR extension messages const char* const FW_KEY_HASH_EXT = " FW KEY HASH"; #ifdef CONFIG_TPMDD /// Global object to store system trusted boot data SystemData systemData; #endif void getTPMs( TARGETING::TargetHandleList& o_tpmList, const TPM_FILTER i_filter) { TRACUCOMP(g_trac_trustedboot,ENTER_MRK "getTPMs(): i_filter=%d", i_filter); o_tpmList.clear(); TARGETING::getAllChips( o_tpmList, TARGETING::TYPE_TPM, (i_filter == TPM_FILTER::ALL_IN_BLUEPRINT) ? false : true); TRACUCOMP(g_trac_trustedboot,EXIT_MRK "getTPMs(): Found %d TPMs", o_tpmList.size()); } _TpmLogMgr* getTpmLogMgr( const TpmTarget* const i_pTpm) { assert(i_pTpm != nullptr,"getTpmLogMgr: BUG! i_pTpm was nullptr"); assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, "getTpmLogMgr: BUG! Expected target to be of TPM type, but " "it was of type 0x%08X",i_pTpm->getAttr()); return reinterpret_cast<_TpmLogMgr*>( i_pTpm->getAttr()); } void setTpmLogMgr( TpmTarget* const i_pTpm, const _TpmLogMgr* const i_pTpmLogMgr) { assert(i_pTpm != nullptr,"setTpmLogMgr: BUG! i_pTpm was nullptr"); assert(i_pTpm->getAttr() == TARGETING::TYPE_TPM, "setTpmLogMgr: BUG! Expected target to be of TPM type, but " "it was of type 0x%08X",i_pTpm->getAttr()); auto pLogMgrPtr = reinterpret_cast( i_pTpmLogMgr); i_pTpm->setAttr< TARGETING::ATTR_HB_TPM_LOG_MGR_PTR>(pLogMgrPtr); } errlHndl_t pcrExtendSeparator(bool i_sendAsync) { errlHndl_t err = NULL; #ifdef CONFIG_TPMDD MessageMode mode = (i_sendAsync) ? MSG_MODE_ASYNC : MSG_MODE_SYNC; TRACUCOMP( g_trac_trustedboot, ENTER_MRK"pcrExtendSeparator()"); Message* msg = Message::factory(MSG_TYPE_SEPARATOR, 0, NULL, mode); assert(msg !=NULL, "BUG! Message is NULL"); if (!i_sendAsync) { int rc = msg_sendrecv(systemData.msgQ, msg->iv_msg); if (0 == rc) { err = msg->iv_errl; msg->iv_errl = NULL; } // Sendrecv failure else { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_TPM_SEPARATOR * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msq_sendrecv() * @devdesc msg_sendrecv() failed * @custdesc Firmware error during system boot */ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_TPM_SEPARATOR, RC_SENDRECV_FAIL, rc, 0, true); err->collectTrace(SECURE_COMP_NAME); err->collectTrace(TRBOOT_COMP_NAME); } delete msg; msg = NULL; } else { int rc = msg_send(systemData.msgQ, msg->iv_msg); if (rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_TPM_SEPARATOR * @reasoncode RC_SEND_FAIL * @userdata1 rc from msq_send() * @devdesc msg_send() failed * @custdesc Firmware error during system boot */ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_TPM_SEPARATOR, RC_SEND_FAIL, rc, 0, true); err->collectTrace(SECURE_COMP_NAME); err->collectTrace(TRBOOT_COMP_NAME); } } TRACUCOMP( g_trac_trustedboot, EXIT_MRK"pcrExtendSeparator() - %s", ((NULL == err) ? "No Error" : "With Error") ); #endif return err; } errlHndl_t pcrExtend(TPM_Pcr i_pcr, EventTypes i_eventType, const uint8_t* i_digest, size_t i_digestSize, const char* i_logMsg, bool i_sendAsync, const TpmTarget* i_pTpm, const bool i_mirrorToLog) { errlHndl_t err = NULL; #ifdef CONFIG_TPMDD MessageMode mode = MSG_MODE_ASYNC; 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)"); TRACUBIN(g_trac_trustedboot, "pcrExtend() digest:", i_digest, i_digestSize); // msgData will be freed when message is freed PcrExtendMsgData* msgData = new PcrExtendMsgData; memset(msgData, 0, sizeof(PcrExtendMsgData)); msgData->mPcrIndex = i_pcr; msgData->mAlgId = TPM_ALG_SHA256; msgData->mEventType = i_eventType; msgData->mDigestSize = (i_digestSize < sizeof(msgData->mDigest) ? i_digestSize : sizeof(msgData->mDigest)); msgData->mSingleTpm = i_pTpm; msgData->mMirrorToLog = i_mirrorToLog; // copy over the incoming digest and truncate to what we need memcpy(msgData->mDigest, i_digest, msgData->mDigestSize); // Truncate logMsg if required 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 ); } if (!i_sendAsync) { mode = MSG_MODE_SYNC; } Message* msg = Message::factory(MSG_TYPE_PCREXTEND, sizeof(PcrExtendMsgData), reinterpret_cast(msgData), mode); // Message owns msgData now msgData = NULL; if (!i_sendAsync) { int rc = msg_sendrecv(systemData.msgQ, msg->iv_msg); if (0 == rc) { err = msg->iv_errl; msg->iv_errl = NULL; } // Sendrecv failure else { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_TPM_PCREXTEND * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msq_sendrecv() * @devdesc msg_sendrecv() failed * @custdesc Firmware error during system boot */ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_TPM_PCREXTEND, RC_SENDRECV_FAIL, rc, 0, true); err->collectTrace(SECURE_COMP_NAME); err->collectTrace(TRBOOT_COMP_NAME); } delete msg; msg = NULL; } else { int rc = msg_send(systemData.msgQ, msg->iv_msg); if (rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_TPM_PCREXTEND * @reasoncode RC_SEND_FAIL * @userdata1 rc from msq_send() * @devdesc msg_send() failed * @custdesc Firmware error during system boot */ err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_TPM_PCREXTEND, RC_SEND_FAIL, rc, 0, true); err->collectTrace(SECURE_COMP_NAME); err->collectTrace(TRBOOT_COMP_NAME); } } TRACUCOMP( g_trac_trustedboot, EXIT_MRK"pcrExtend() - %s", ((NULL == err) ? "No Error" : "With Error") ); #endif return err; } errlHndl_t extendPnorSectionHash( const SECUREBOOT::ContainerHeader& i_conHdr, const void* const i_vaddr, const PNOR::SectionId i_sec) { errlHndl_t pError = nullptr; #ifdef CONFIG_TPMDD do { PNOR::SectionInfo_t sectionInfo; pError = PNOR::getSectionInfo(i_sec,sectionInfo); if(pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to " "getSectionInfo() with section ID = %d.", i_sec); break; } TRACDCOMP(g_trac_trustedboot, ENTER_MRK " extendPnorSectionHash for " "section: %s",sectionInfo.name); const size_t protectedSize = i_conHdr.payloadTextSize(); // Generate pcr extension message char swKeyMsg[strlen(sectionInfo.name) + strlen(FW_KEY_HASH_EXT) + 1]; memset(swKeyMsg, 0, sizeof(swKeyMsg)); strcat(swKeyMsg,sectionInfo.name); strcat(swKeyMsg,FW_KEY_HASH_EXT); TPM_Pcr pnorHashPcr = PCR_0; EventTypes swKeyHashEventType = TRUSTEDBOOT::EV_PLATFORM_CONFIG_FLAGS; EventTypes pnorHashEventType = TRUSTEDBOOT::EV_POST_CODE; // PAYLOAD is the only section that needs its hash extended to PCR_4 if (i_sec == PNOR::PAYLOAD) { pnorHashPcr = PCR_4; swKeyHashEventType = TRUSTEDBOOT::EV_COMPACT_HASH; pnorHashEventType = TRUSTEDBOOT::EV_COMPACT_HASH; } else if(PNOR::isCoreRootOfTrustSection(i_sec)) { pnorHashEventType = TRUSTEDBOOT::EV_S_CRTM_CONTENTS; } // Extend swKeyHash to the next PCR after the hash extension PCR. const TPM_Pcr swKeyHashPcr = static_cast(pnorHashPcr + 1); if (SECUREBOOT::enabled()) { // If secureboot is enabled, use protected hash in header pError = TRUSTEDBOOT::pcrExtend(pnorHashPcr, pnorHashEventType, reinterpret_cast(i_conHdr.payloadTextHash()), sizeof(SHA512_t), sectionInfo.name); if (pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to " "pcrExtend() (extend payload text hash) for section %s.", sectionInfo.name); break; } // Extend SW public key hash pError = TRUSTEDBOOT::pcrExtend(swKeyHashPcr, swKeyHashEventType, reinterpret_cast(i_conHdr.swKeyHash()), sizeof(SHA512_t), swKeyMsg); if (pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to " "pcrExtend() (extend SW public key hash) for section %s.", sectionInfo.name); break; } } else { // If secureboot is not enabled, measure protected section SHA512_t hash = {0}; SECUREBOOT::hashBlob(i_vaddr, protectedSize, hash); pError = TRUSTEDBOOT::pcrExtend(pnorHashPcr, pnorHashEventType, hash, sizeof(SHA512_t), sectionInfo.name); if (pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to " "pcrExtend() (extend payload text) for section %s.", sectionInfo.name); break; } } } while(0); TRACDCOMP(g_trac_trustedboot, EXIT_MRK " extendPnorSectionHash"); #endif return pError; } errlHndl_t extendBaseImage() { errlHndl_t pError = nullptr; #ifdef CONFIG_TPMDD TRACDCOMP(g_trac_trustedboot, ENTER_MRK " extendBaseImage()"); do { // Query the HBB header and code address const void* pHbbHeader = nullptr; (void)SECUREBOOT::baseHeader().getHeader( pHbbHeader); // Fatal code bug if either address is nullptr if(pHbbHeader == nullptr) { assert(false,"BUG! In extendBaseImage(), cached header address is " "nullptr"); } TRACDBIN(g_trac_trustedboot,"Base Header",pHbbHeader, TRUSTEDBOOT::DEFAULT_BIN_TRACE_SIZE); // Build a container header object from the raw header SECUREBOOT::ContainerHeader hbbContainerHeader; pError = hbbContainerHeader.setHeader(pHbbHeader); if (pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK"extendBaseImage() setheader failed"); break; } // TPM extension of PNOR sections operates differently when SecureMode is // enabled/disabled. Provide all possible info and let TPM code handle // the logic PNOR::SectionInfo_t l_info; pError = getSectionInfo(PNOR::HB_BASE_CODE, l_info); if(pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK "Failed in call to " "getSectionInfo for HBB section"); break; } if(l_info.vaddr == 0) { assert(false,"BUG! In extendBaseImage(), HBB virtual address was 0"); } const void* pHbbVa = reinterpret_cast(l_info.vaddr); TRACDBIN(g_trac_trustedboot,"PNOR Base Code",pHbbVa, TRUSTEDBOOT::DEFAULT_BIN_TRACE_SIZE); // Extend the HBB measurement to the TPM pError = extendPnorSectionHash( hbbContainerHeader, pHbbVa, PNOR::HB_BASE_CODE); if(pError) { TRACFCOMP(g_trac_trustedboot, ERR_MRK "Failed in call to " "extendPnorSectionHash() for HBB section."); break; } } while(0); TRACDCOMP(g_trac_trustedboot, EXIT_MRK " extendBaseImage()"); #endif return pError; } void initBackupTpm() { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD Message* l_msg = Message::factory(MSG_TYPE_INIT_BACKUP_TPM, 0, nullptr, MSG_MODE_SYNC); int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc == 0) { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } else { TRACFCOMP(g_trac_trustedboot, "Error occurred while sending message to" " the TPM daemon. RC = %d", l_rc); /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @reasoncode RC_SENDRECV_FAIL * @moduleid MOD_INIT_BACKUP_TPM * @userdata1 rc from msq_sendrecv() * @devdesc msg_sendrecv() failed * @custdesc Trusted Boot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_INIT_BACKUP_TPM, RC_SENDRECV_FAIL, l_rc, 0, true); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } delete l_msg; l_msg = nullptr; if(l_errl) { TARGETING::Target* l_backupTpm = nullptr; getBackupTpm(l_backupTpm); if(l_backupTpm) { tpmMarkFailed(l_backupTpm, l_errl); } } #endif } errlHndl_t testCmpPrimaryAndBackupTpm() { errlHndl_t l_err = nullptr; #ifdef CONFIG_TPMDD TARGETING::Target* l_primaryTpm = nullptr; TARGETING::Target* l_backupTpm = nullptr; bool l_errorOccurred = false; BackupTpmTestFailures l_rc = TPM_TEST_NO_ERROR; do { getPrimaryTpm(l_primaryTpm); if(!l_primaryTpm) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: primary TPM not found;" "skipping test"); break; } getBackupTpm(l_backupTpm); if(!l_backupTpm) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: backup TPM not found;" "skipping test"); break; } auto l_primaryHwasState = l_primaryTpm->getAttr< TARGETING::ATTR_HWAS_STATE>(); if(!(l_primaryHwasState.present && l_primaryHwasState.functional)) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: primary TPM" "is not present or not functional;" "skipping the test."); break; } auto l_backupHwasState = l_backupTpm->getAttr(); if(!(l_backupHwasState.present && l_backupHwasState.functional)) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: backup TPM" "is not present or not functional;" "skipping the test."); break; } auto * const pTpmLogMgr = getTpmLogMgr(l_primaryTpm); auto * const bTpmLogMgr = getTpmLogMgr(l_backupTpm); if(!pTpmLogMgr || !bTpmLogMgr) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: TPM log manager(s)" " is(are) uninitialized"); l_errorOccurred = true; l_rc = TPM_TEST_LOGS_NOT_INITIALIZED; break; } if(TpmLogMgr_getLogSize(bTpmLogMgr) == TpmLogMgr_getLogSize(pTpmLogMgr)) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: the sizes of TPM logs match"); } else { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: log size mismatch." " Primary log size: %d; backup log size: %d.", TpmLogMgr_getLogSize(pTpmLogMgr), TpmLogMgr_getLogSize(bTpmLogMgr)); l_errorOccurred = true; l_rc = TPM_TEST_LOG_SIZE_MISMATCH; break; } int l_count = 0; TCG_PCR_EVENT2 l_pEventLog = {0}; TCG_PCR_EVENT2 l_bEventLog = {0}; // Skip the first entry which is the header const uint8_t* l_pEventHdl = TpmLogMgr_getFirstEvent(pTpmLogMgr); const uint8_t* l_bEventHdl = TpmLogMgr_getFirstEvent(bTpmLogMgr); // Match the logs while(l_pEventHdl != nullptr && l_bEventHdl != nullptr) { // Other (than the header) events need to be processed l_pEventHdl = TpmLogMgr_getNextEvent(pTpmLogMgr, l_pEventHdl, &l_pEventLog, &l_errorOccurred); if(l_errorOccurred) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: Unmarshaling error occurred."); l_rc = TPM_TEST_UNMARSHAL_ERROR; break; } l_bEventHdl = TpmLogMgr_getNextEvent(bTpmLogMgr, l_bEventHdl, &l_bEventLog, &l_errorOccurred); if(l_errorOccurred) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: Unmarshaling error occurred."); l_rc = TPM_TEST_UNMARSHAL_ERROR; break; } if(memcmp(&l_pEventLog, &l_bEventLog, sizeof(TCG_PCR_EVENT2))) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: log #%d does not match", l_count); TRACFBIN(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: primary TPM's log:", &l_pEventLog, sizeof(TCG_PCR_EVENT2)); TRACFBIN(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: backup TPM's log:", &l_bEventLog, sizeof(TCG_PCR_EVENT2)); l_errorOccurred = true; l_rc = TPM_TEST_LOG_MISMATCH; break; } else { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: log #%d matches", l_count); } l_count++; } //while if(l_err || l_errorOccurred) { break; } TPM_Pcr l_pcrRegs[8] = {PCR_0, PCR_1, PCR_2, PCR_3, PCR_4, PCR_5, PCR_6, PCR_7}; TPM_Alg_Id l_algIds[2] = {TPM_ALG_SHA1, TPM_ALG_SHA256}; size_t l_sizeToAllocate = std::max(getDigestSize(TPM_ALG_SHA1), getDigestSize(TPM_ALG_SHA256)); uint8_t* l_pDigest = new uint8_t[l_sizeToAllocate](); uint8_t* l_bDigest = new uint8_t[l_sizeToAllocate](); size_t l_digestSize = 0; // Match the contents of the PCR regs for(const auto l_algId : l_algIds) { l_digestSize = getDigestSize(l_algId); for(const auto l_pcrReg : l_pcrRegs) { l_err = tpmCmdPcrRead(l_primaryTpm, l_pcrReg, l_algId, l_pDigest, l_digestSize); if(l_err) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: failed to read PCR %d" " of primary TPM; algId = 0x%.04x", l_pcrReg, l_algId); break; } l_err = tpmCmdPcrRead(l_backupTpm, l_pcrReg, l_algId, l_bDigest, l_digestSize); if(l_err) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: failed to read PCR %d" " of backup TPM; algId = 0x%.04x", l_pcrReg, l_algId); break; } if(memcmp(l_pDigest, l_bDigest, l_digestSize)) { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: digests of PCR %d" " algId 0x%.04x do not match!", l_pcrReg, l_algId); TRACFBIN(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: contents of primary TPM's" " PCR:", l_pDigest, l_digestSize); TRACFBIN(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: contents of backup TPM's" " PCR:", l_bDigest, l_digestSize); l_rc = TPM_TEST_DIGEST_MISMATCH; l_errorOccurred = true; break; } else { TRACFCOMP(g_trac_trustedboot, "testCmpPrimaryAndBackupTpm: digests of PCR %d, algId" " 0x%.04x match", l_pcrReg, l_algId); } } // pcrReg if(l_err || l_errorOccurred) { break; } } // algId delete l_pDigest; delete l_bDigest; l_pDigest = l_bDigest = nullptr; } while(0); if(!l_err && l_errorOccurred) { /*@ * @errortype * @reasoncode RC_BACKUP_TPM_TEST_FAIL * @severity ERRL_SEV_UNRECOVERABLE * @moduleid MOD_TEST_CMP_PRIMARY_AND_BACKUP_TPM * @userdata1 return code * @userdata2 0 * @devdesc TPM testcase error. See the return code for details. * @custdesc Trusted Boot failure. */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_TEST_CMP_PRIMARY_AND_BACKUP_TPM, RC_BACKUP_TPM_TEST_FAIL, l_rc, 0, true /*Add HB SW Callout*/); l_err->collectTrace(SECURE_COMP_NAME); l_err->collectTrace(TRBOOT_COMP_NAME); } #endif return l_err; } errlHndl_t flushTpmQueue() { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD TRACFCOMP(g_trac_trustedboot, ENTER_MRK"flushTpmQueue()"); Message* l_msg = Message::factory(MSG_TYPE_FLUSH, 0, nullptr, MSG_MODE_SYNC); assert(l_msg != nullptr, "TPM flush message is nullptr"); int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_FLUSH_TPM_QUEUE * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msq_sendrecv() * @devdesc msg_sendrecv() failed trying to send flush message to * TPM daemon * @custdesc Trusted boot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_FLUSH_TPM_QUEUE, RC_SENDRECV_FAIL, l_rc, 0, true); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } else { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } delete l_msg; l_msg = nullptr; TRACFCOMP(g_trac_trustedboot, EXIT_MRK"flushTpmQueue()"); #endif return l_errl; } errlHndl_t createAttestationKeys(TpmTarget* i_target) { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD Message* l_msg = nullptr; TpmTargetData* l_data = new TpmTargetData{i_target}; l_msg = Message::factory(MSG_TYPE_CREATE_ATT_KEYS, sizeof(*l_data), reinterpret_cast(l_data), MSG_MODE_SYNC); assert(l_msg != nullptr, "createAttestationKeys: l_msg is nullptr"); l_data = nullptr; //l_msg now owns l_data int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_CREATE_ATT_KEYS * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msg_sendrecv * @userdata2 TPM HUID * @devdesc msg_sendrecv failed for createAttestationKeys * @custdesc trustedboot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_CREATE_ATT_KEYS, RC_SENDRECV_FAIL, l_rc, TARGETING::get_huid(i_target), ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } else { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } if(l_msg) { delete l_msg; l_msg = nullptr; } #endif return l_errl; } errlHndl_t readAKCertificate(TpmTarget* i_target, AKCertificate_t* o_data) { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD Message* l_msg = nullptr; ReadAKCertData* l_data = new ReadAKCertData {i_target, o_data}; l_msg = Message::factory(MSG_TYPE_READ_AK_CERT, sizeof(*l_data), reinterpret_cast(l_data), MSG_MODE_SYNC); assert(l_msg != nullptr, "readAKCertificate: l_msg is nullptr"); l_data = nullptr; // l_msg now owns l_data int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_READ_AK_CERT * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msg_sendrecv * @userdata2 TPM HUID * @devdesc msg_sendrecv failed for readAKCertificate * @custdesc trustedboot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_READ_AK_CERT, RC_SENDRECV_FAIL, l_rc, TARGETING::get_huid(i_target), ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } else { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } if(l_msg) { delete l_msg; l_msg = nullptr; } #endif return l_errl; } errlHndl_t generateQuote(TpmTarget* i_target, MasterTpmNonce_t* i_masterNonce, QuoteDataOut* o_data) { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD Message* l_msg = nullptr; GenQuoteData* l_data = new GenQuoteData{i_target, i_masterNonce, o_data}; l_msg = Message::factory(MSG_TYPE_GEN_QUOTE, sizeof(*l_data), reinterpret_cast(l_data), MSG_MODE_SYNC); assert(l_msg != nullptr, "generateQuote: l_msg is nullptr"); l_data = nullptr; //l_msg now owns l_data int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_GEN_QUOTE * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msg_sendrecv * @userdata2 TPM HUID * @devdesc msg_sendrecv failed for generateQuote * @custdesc trustedboot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_GEN_QUOTE, RC_SENDRECV_FAIL, l_rc, TARGETING::get_huid(i_target), ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } else { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } if(l_msg) { delete l_msg; l_msg = nullptr; } #endif return l_errl; } errlHndl_t flushContext(TpmTarget* i_target) { errlHndl_t l_errl = nullptr; #ifdef CONFIG_TPMDD Message* l_msg = nullptr; TpmTargetData* l_data = new TpmTargetData{i_target}; l_msg = Message::factory(MSG_TYPE_FLUSH_CONTEXT, sizeof(*l_data), reinterpret_cast(l_data), MSG_MODE_SYNC); assert(l_msg != nullptr, "flushContext: l_msg is nullptr"); l_data = nullptr; int l_rc = msg_sendrecv(systemData.msgQ, l_msg->iv_msg); if(l_rc) { /*@ * @errortype ERRL_SEV_UNRECOVERABLE * @moduleid MOD_FLUSH_CONTEXT * @reasoncode RC_SENDRECV_FAIL * @userdata1 rc from msg_sendrecv * @userdata2 TPM HUID * @devdesc msg_sendrecv failed for TPM2_FlushContext * @custdesc trustedboot failure */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MOD_FLUSH_CONTEXT, RC_SENDRECV_FAIL, l_rc, TARGETING::get_huid(i_target), ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); l_errl->collectTrace(SECURE_COMP_NAME); l_errl->collectTrace(TRBOOT_COMP_NAME); } else { l_errl = l_msg->iv_errl; l_msg->iv_errl = nullptr; } if(l_msg) { delete l_msg; l_msg = nullptr; } #endif return l_errl; } } // end TRUSTEDBOOT