From 26f7f6d12b118253c3ba841dacedf34beaa93ff9 Mon Sep 17 00:00:00 2001 From: Ilya Smirnov Date: Thu, 3 Jan 2019 15:09:17 -0600 Subject: Trustedboot: GetRandom API Changes New Secure Multinode Comm protocol calls for generation of random number that is 32 bytes in size. This commit extends the existing GetRandom API to be able to accept a size of the random number to be generated by TPM. Change-Id: Ic6fc1705594f51f121ff75aaa489d6d32fe41409 RTC: 202364 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70116 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Nicholas E. Bofferding Tested-by: FSP CI Jenkins Reviewed-by: Michael Baiocchi Reviewed-by: Daniel M. Crowell --- src/usr/secureboot/trusted/base/trustedbootMsg.H | 5 +- src/usr/secureboot/trusted/test/trustedbootTest.H | 6 +- src/usr/secureboot/trusted/trustedboot.C | 76 ++++++++++++++++++----- 3 files changed, 69 insertions(+), 18 deletions(-) (limited to 'src/usr/secureboot/trusted') diff --git a/src/usr/secureboot/trusted/base/trustedbootMsg.H b/src/usr/secureboot/trusted/base/trustedbootMsg.H index b327d6375..95a52a6e4 100644 --- a/src/usr/secureboot/trusted/base/trustedbootMsg.H +++ b/src/usr/secureboot/trusted/base/trustedbootMsg.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -76,7 +76,8 @@ namespace TRUSTEDBOOT struct GetRandomMsgData { TARGETING::Target* i_pTpm; // the TPM to obtain random data from - uint64_t o_randNum; // the random data is populated here + size_t i_randNumSize; // the size (in bytes) of the rand number + uint8_t* o_randNum; // the random data is populated here }; // Trustedboot message class diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H index 28917a959..83792cba0 100755 --- a/src/usr/secureboot/trusted/test/trustedbootTest.H +++ b/src/usr/secureboot/trusted/test/trustedbootTest.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -905,7 +905,9 @@ class TrustedBootTest: public CxxTest::TestSuite for (auto pTpm: tpmList) { uint64_t randNum = 0; - err = TRUSTEDBOOT::GetRandom(pTpm, randNum); + err = TRUSTEDBOOT::GetRandom(pTpm, + reinterpret_cast(&randNum), + sizeof(randNum)); num_ops ++; if(err) { diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C index 28122df6c..5f5e711fd 100644 --- a/src/usr/secureboot/trusted/trustedboot.C +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -1547,6 +1547,34 @@ void* tpmDaemon(void* unused) assert(msgData != nullptr, "Trusted boot message data pointer is null"); auto l_pTpm = msgData->i_pTpm; + size_t l_randNumSize = msgData->i_randNumSize; + + if(l_randNumSize > sizeof(TPM2B_DIGEST)) + { + TRACFCOMP( g_trac_trustedboot, + ERR_MRK"TPM GetRandom: The size of the requested random number (%d) is larger than max size the TPM can return (%d).", l_randNumSize, sizeof(TPM2B_DIGEST)); + /*@ + * @errortype ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_TPM_TPMDAEMON + * @reasoncode RC_RAND_NUM_TOO_BIG + * @userdata1 The size of requested random number + * @userdata2 The maximum random number size + * @devdesc Attempted to request a random number that + * is bigger than the max a TPM can provide + * @custdesc Trusted boot failure + */ + err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_TPM_TPMDAEMON, + RC_RAND_NUM_TOO_BIG, + l_randNumSize, + sizeof(TPM2B_DIGEST), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + + tb_msg->iv_errl = err; + err = nullptr; + break; + } err = validateTpmHandle(l_pTpm); if (err) @@ -1559,11 +1587,10 @@ void* tpmDaemon(void* unused) size_t dataSize = sizeof(dataBuf); auto cmd = reinterpret_cast(dataBuf); auto resp = reinterpret_cast(dataBuf); - uint64_t randNum = 0; cmd->base.tag = TPM_ST_NO_SESSIONS; cmd->base.commandCode = TPM_CC_GetRandom; - cmd->bytesRequested = sizeof(randNum); + cmd->bytesRequested = l_randNumSize; err = tpmTransmitCommand(l_pTpm, dataBuf, dataSize, TPM_LOCALITY_0); @@ -1588,15 +1615,16 @@ void* tpmDaemon(void* unused) RC_UNREACHABLE_TPM, TARGETING::get_huid(l_pTpm), 0, - true); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); err->plid(l_errPlid); tb_msg->iv_errl = err; err = nullptr; } else { - memcpy(&randNum, resp->randomBytes.buffer,sizeof(randNum)); - msgData->o_randNum = randNum; + memcpy(msgData->o_randNum, + resp->randomBytes.buffer, + l_randNumSize); } } break; @@ -1669,7 +1697,7 @@ errlHndl_t validateTpmHandle(const TpmTarget* i_pTpm) i_pTpm->getAttr() != TARGETING::TYPE_TPM) { TRACFCOMP(g_trac_trustedboot, - ERR_MRK"Invalid TPM handle passed to GetRandom() huid = 0x%08X", + ERR_MRK"Invalid TPM handle passed to validateTpmHandle: huid = 0x%08X", TARGETING::get_huid(i_pTpm)); /*@ * @errortype ERRL_SEV_UNRECOVERABLE @@ -1694,7 +1722,7 @@ errlHndl_t validateTpmHandle(const TpmTarget* i_pTpm) if (!l_tpmHwasState.functional) { TRACFCOMP(g_trac_trustedboot, - ERR_MRK"Non functional TPM handle passed to GetRandom() huid = 0x%08X", + ERR_MRK"Non functional TPM handle passed to validateTpmHandle: huid = 0x%08X", TARGETING::get_huid(i_pTpm)); /*@ * @errortype ERRL_SEV_UNRECOVERABLE @@ -1870,17 +1898,22 @@ errlHndl_t tpmDrtmReset(TpmTarget* const i_pTpm) #endif #ifdef CONFIG_TPMDD -errlHndl_t GetRandom(const TpmTarget* i_pTpm, uint64_t& o_randNum) +errlHndl_t GetRandom(const TpmTarget* i_pTpm, + uint8_t* o_randNum, + const size_t i_randNumSize) { errlHndl_t err = nullptr; Message* msg = nullptr; + auto pData = new struct GetRandomMsgData; + do { - auto pData = new struct GetRandomMsgData; memset(pData, 0, sizeof(*pData)); - pData->i_pTpm = const_cast(i_pTpm); + pData->i_randNumSize = i_randNumSize; + pData->o_randNum = new uint8_t[i_randNumSize]; + memset(pData->o_randNum, 0, i_randNumSize); msg = Message::factory(MSG_TYPE_GETRANDOM, sizeof(*pData), reinterpret_cast(pData), MSG_MODE_SYNC); @@ -1914,7 +1947,7 @@ errlHndl_t GetRandom(const TpmTarget* i_pTpm, uint64_t& o_randNum) RC_SENDRECV_FAIL, rc, TARGETING::get_huid(i_pTpm), - true); + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); break; } @@ -1922,10 +1955,23 @@ errlHndl_t GetRandom(const TpmTarget* i_pTpm, uint64_t& o_randNum) assert(pData != nullptr, "BUG! Completed send/recv to random num generator has null data ptr!"); - o_randNum = pData->o_randNum; + memcpy(o_randNum, pData->o_randNum, pData->i_randNumSize); } while (0); + // If an error occurs before the reponse is written, then pData + // will be nullptr and dereferencing o_randNum will cause crashes. + // So, we need to check for pData before attempting to delete the + // o_randNum. + if(pData) + { + if(pData->o_randNum) + { + delete[](pData->o_randNum); + pData->o_randNum = nullptr; + } + } + if (msg != nullptr) { delete msg; // also deletes the msg->iv_data @@ -1953,7 +1999,9 @@ errlHndl_t poisonTpm(const TpmTarget* i_pTpm) // Note: GetRandom validates the TPM handle internally and returns an // error log if invalid - l_errl = GetRandom(i_pTpm, l_randNum); + l_errl = GetRandom(i_pTpm, + reinterpret_cast(&l_randNum), + sizeof(l_randNum)); if (l_errl) { -- cgit v1.2.1