Skip to content

Commit

Permalink
New API to Retrieve Random Number from the TPM
Browse files Browse the repository at this point in the history
A new programming interface allows us to obtain random numbers
from the TPM more easily (i.e. in a more high-level way).

Change-Id: Ibd3d3b320411bea146d6eab4d1a59ca760bc726c
RTC:191000
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57802
Reviewed-by: ILYA SMIRNOV <ismirno@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
popfuture authored and dcrowell77 committed May 11, 2018
1 parent 7145f5c commit 98bee5b
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 11 deletions.
8 changes: 6 additions & 2 deletions src/include/usr/secureboot/trustedboot_reasoncodes.H
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,16 @@ namespace TRUSTEDBOOT
MOD_TPM_SYNCRESPONSE = 0x0C,
MOD_TPM_SEPARATOR = 0x0D,
MOD_TPM_CMD_GETCAPNVINDEX = 0x0E,

MOD_TPMLOGMGR_INITIALIZE = 0x10,
MOD_TPMLOGMGR_ADDEVENT = 0x11,
MOD_TPMLOGMGR_INITIALIZEEXISTLOG = 0x12,
MOD_TPMLOGMGR_GETDEVTREEINFO = 0x13,
MOD_TPM_MARK_FAILED = 0x14,
MOD_INIT_BACKUP_TPM = 0x15,
MOD_DO_INIT_BACKUP_TPM = 0x16,
MOD_TEST_CMP_PRIMARY_AND_BACKUP_TPM = 0x17
MOD_TEST_CMP_PRIMARY_AND_BACKUP_TPM = 0x17,
MOD_TPM_GETRANDOM = 0x18,
MOD_VALIDATE_TPM_HANDLE = 0x19,
};

enum TRUSTEDReasonCode
Expand Down Expand Up @@ -97,6 +98,9 @@ namespace TRUSTEDBOOT
RC_TPM_NVINDEX_VALIDATE_FAIL = TRBOOT_COMP_ID | 0xB5,
RC_TPMLOGMGR_INITIALIZE_FAIL = TRBOOT_COMP_ID | 0xB6,
RC_BACKUP_TPM_TEST_FAIL = TRBOOT_COMP_ID | 0xB7,
RC_INVALID_TPM_HANDLE = TRBOOT_COMP_ID | 0xB8,
RC_NON_FUNCTIONAL_TPM_HANDLE = TRBOOT_COMP_ID | 0xB9,
RC_UNREACHABLE_TPM = TRBOOT_COMP_ID | 0xBA,
};
#ifdef __cplusplus
}
Expand Down
27 changes: 27 additions & 0 deletions src/include/usr/secureboot/trustedbootif.H
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <secureboot/containerheader.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <config.h>

namespace TRUSTEDBOOT
{
Expand Down Expand Up @@ -233,6 +234,32 @@ namespace TRUSTEDBOOT
uint64_t i_xscomAddr,
uint32_t i_i2cMasterOffset);

#ifdef CONFIG_TPMDD
/**
* @brief Generate random numbers via TPM hardware.
*
* @parm[in] i_pTpm Pointer to TPM target. In order to succeed, it cannot
* be null and must be a TPM target pointer. The TPM target must
* be functional. All of these conditions must be met or an error
* log will result.
*
* @parm[out] o_randNum A uint64_t reference to be filled with random bits.
*
* @return errlHndl_t nullptr on success or an error log pointer on failure
*/
errlHndl_t GetRandom(const TpmTarget* i_pTpm, uint64_t& o_randNum);
#endif

/**
* @brief Helper function for validating TPM handles. Returns an error log
* if the supplied TPM is null, not a TPM target, or not functional.
*
* @parm[in] i_pTpm Pointer to the TPM target to be checked.
*
* @return errlHndl_t nullptr if valid or error log otherwise.
*/
errlHndl_t validateTpmHandle(const TpmTarget* i_pTpm);

/**
* @brief Checks whether the node has a present and functioning primary TPM.
* @retval true if a present and functional primary TPM is available;
Expand Down
9 changes: 8 additions & 1 deletion src/usr/secureboot/trusted/base/trustedbootMsg.H
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ namespace TRUSTEDBOOT
MSG_TYPE_SEPARATOR,
MSG_TYPE_SHUTDOWN,
MSG_TYPE_INIT_BACKUP_TPM,
MSG_TYPE_LAST = MSG_TYPE_INIT_BACKUP_TPM
MSG_TYPE_GETRANDOM,
MSG_TYPE_LAST = MSG_TYPE_GETRANDOM,
};

/// PCREXTEND message data
Expand All @@ -69,6 +70,12 @@ namespace TRUSTEDBOOT
char mLogMsg[MAX_TPM_LOG_MSG];
};

struct GetRandomMsgData
{
TARGETING::Target* i_pTpm; // the TPM to obtain random data from
uint64_t o_randNum; // the random data is populated here
};

// Trustedboot message class
class Message
{
Expand Down
73 changes: 73 additions & 0 deletions src/usr/secureboot/trusted/base/trustedboot_base.C
Original file line number Diff line number Diff line change
Expand Up @@ -794,4 +794,77 @@ errlHndl_t testCmpPrimaryAndBackupTpm()
return l_err;
}

#ifdef CONFIG_TPMDD
errlHndl_t GetRandom(const TpmTarget* i_pTpm, uint64_t& o_randNum)
{
errlHndl_t err = nullptr;
Message* msg = nullptr;

do {

auto pData = new struct GetRandomMsgData;
memset(pData, 0, sizeof(*pData));

pData->i_pTpm = const_cast<TpmTarget*>(i_pTpm);

msg = Message::factory(MSG_TYPE_GETRANDOM, sizeof(*pData),
reinterpret_cast<uint8_t*>(pData), MSG_MODE_SYNC);

assert(msg != nullptr, "BUG! Message is null");
pData = nullptr; // Message owns msgData now

int rc = msg_sendrecv(systemData.msgQ, msg->iv_msg);
if (0 == rc)
{
err = msg->iv_errl;
msg->iv_errl = nullptr; // taking over ownership of error log
if (err != nullptr)
{
break;
}
}
else // sendrecv failure
{
/*@
* @errortype ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_TPM_GETRANDOM
* @reasoncode RC_SENDRECV_FAIL
* @userdata1 rc from msq_sendrecv()
* @userdata2 TPM HUID if it's not nullptr
* @devdesc msg_sendrecv() failed
* @custdesc Trusted boot failure
*/
err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MOD_TPM_GETRANDOM,
RC_SENDRECV_FAIL,
rc,
TARGETING::get_huid(i_pTpm),
true);
break;
}

pData = reinterpret_cast<struct GetRandomMsgData*>(msg->iv_data);
assert(pData != nullptr,
"BUG! Completed send/recv to random num generator has null data ptr!");

o_randNum = pData->o_randNum;

} while (0);

if (msg != nullptr)
{
delete msg; // also deletes the msg->iv_data
msg = nullptr;
}

if (err)
{
err->collectTrace(SECURE_COMP_NAME);
err->collectTrace(TRBOOT_COMP_NAME);
}

return err;
}
#endif // CONFIG_TPMDD

} // end TRUSTEDBOOT
50 changes: 49 additions & 1 deletion src/usr/secureboot/trusted/test/trustedbootTest.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -45,6 +45,7 @@
#include "../trustedboot.H"
#include "../trustedbootCmds.H"
#include "../tpmLogMgr.H"
#include <config.h>

using namespace TRUSTEDBOOT;

Expand Down Expand Up @@ -885,6 +886,53 @@ class TrustedBootTest: public CxxTest::TestSuite
EXIT_MRK "testReadPCR: %d/%d fails",
fails, num_ops );
}

/**
* @brief TPM GetRandom
*/
void testGetRandom ( void )
{
TRACFCOMP( g_trac_trustedboot,
ENTER_MRK "testGetRandom" );

errlHndl_t err = nullptr;
size_t fails = 0;
size_t num_ops = 0;

// Just for fun generate random numbers for each of the TPMs
TARGETING::TargetHandleList tpmList;
TRUSTEDBOOT::getTPMs(tpmList, TRUSTEDBOOT::TPM_FILTER::ALL_FUNCTIONAL);
for (auto pTpm: tpmList)
{
uint64_t randNum = 0;
err = TRUSTEDBOOT::GetRandom(pTpm, randNum);
num_ops ++;
if(err)
{
fails++;
TS_FAIL( "testGetRandom: Error detected" );
errlCommit( err,
TRBOOT_COMP_ID );
delete err;
err = nullptr;
}
else if (randNum == 0) // if random number is zero still
{
fails++;
TS_FAIL( "testGetRandom: got zero for a random number");
}
else
{

TRACUCOMP(g_trac_trustedboot, "testGetRandom: GetRandom returned as expected. Random number 0x%.16llX",randNum);
}

}

TRACFCOMP( g_trac_trustedboot,
EXIT_MRK "testGetRandom: %d/%d fails",
fails, num_ops );
}
};

#endif
19 changes: 18 additions & 1 deletion src/usr/secureboot/trusted/trustedTypes.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -105,6 +105,7 @@ namespace TRUSTEDBOOT
// Command Codes
TPM_CC_Startup = 0x00000144,
TPM_CC_GetCapability = 0x0000017A,
TPM_CC_GetRandom = 0x0000017B,
TPM_CC_PCR_Read = 0x0000017E,
TPM_CC_PCR_Extend = 0x00000182,

Expand Down Expand Up @@ -453,6 +454,22 @@ namespace TRUSTEDBOOT
size_t* io_tpmBufSize,
size_t i_outBufSize);

/// Incoming GetRandom structure
struct _TPM2_GetRandomIn
{
TPM2_BaseIn base;
uint16_t bytesRequested;
} PACKED;
typedef struct _TPM2_GetRandomIn TPM2_GetRandomIn;

/// Outgoing GetRandom structure
struct _TPM2_GetRandomOut
{
TPM2_BaseOut base;
TPM2B_DIGEST randomBytes;
} PACKED;
typedef struct _TPM2_GetRandomOut TPM2_GetRandomOut;

/// TPM Authorization structure
/// This is not the full structure and only works for PW auth with NULL PW
struct _TPMS_AUTH_COMMAND
Expand Down

0 comments on commit 98bee5b

Please sign in to comment.