Skip to content

Commit

Permalink
Secureboot: Add New TPM Commands For Nodecomm
Browse files Browse the repository at this point in the history
This commit adds four new TPM commands, and APIs thereto,
for enhanced secure multinode communication protocol. The
TPM commands are the base for the new protocol and will be
used as part of it.

Change-Id: I080ff87cd6001b5d2e13ae350a379cbc2c92bfcf
RTC: 202364
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69725
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@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>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Ilya Smirnov authored and dcrowell77 committed Jan 18, 2019
1 parent 6a5388b commit 868b68d
Show file tree
Hide file tree
Showing 11 changed files with 973 additions and 30 deletions.
9 changes: 9 additions & 0 deletions src/include/usr/secureboot/trustedboot_reasoncodes.H
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ namespace TRUSTEDBOOT
MOD_TEST_CMP_PRIMARY_AND_BACKUP_TPM = 0x17,
MOD_TPM_GETRANDOM = 0x18,
MOD_VALIDATE_TPM_HANDLE = 0x19,
MOD_TPM_CMD_CREATE_ATTEST = 0x1A,
MOD_CREATE_ATT_KEYS = 0x1B,
MOD_READ_AK_CERT = 0x1C,
MOD_TPM_CMD_READ_AK_CERT = 0x1D,
MOD_TPM_CMD_GEN_QUOTE = 0x1E,
MOD_GEN_QUOTE = 0x1F,
MOD_TPM_CMD_FLUSH_CONTEXT = 0x20,
MOD_FLUSH_CONTEXT = 0x21,
};

enum TRUSTEDReasonCode
Expand Down Expand Up @@ -104,6 +112,7 @@ namespace TRUSTEDBOOT
RC_NON_FUNCTIONAL_TPM_HANDLE = TRBOOT_COMP_ID | 0xB9,
RC_UNREACHABLE_TPM = TRBOOT_COMP_ID | 0xBA,
RC_RAND_NUM_TOO_BIG = TRBOOT_COMP_ID | 0xBB,
RC_TPM_BAD_RESP = TRBOOT_COMP_ID | 0xBC,
};
#ifdef __cplusplus
}
Expand Down
77 changes: 72 additions & 5 deletions src/include/usr/secureboot/trustedbootif.H
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,34 @@ namespace TRUSTEDBOOT

struct _TpmLogMgr;

// Structure that contains the TPM quote data and the size thereof
struct _QuoteDataOut
{
size_t size; // the size (bytes) of the data pointer
uint8_t* data; // the actual quote data
} PACKED;
typedef struct _QuoteDataOut QuoteDataOut;

// Hostboot code just maps the TpmTarget type, which shared APIs use, as a
// targeting target
typedef TARGETING::Target TpmTarget;

enum
{
// The size of AK certificate from the TPM, in bytes
TPM_NV_DATA_SIZE = 0x1F4,
// The size of the master nonce, in bytes
TPM_NONCE_SIZE_BYTES = 0x20,
};

// The structure that defines the size of the TPM AK certificate
// (in bytes)
typedef uint8_t AKCertificate_t[TPM_NV_DATA_SIZE];

// The structure that defines the size of the master node nonce
// (in bytes)
typedef uint8_t MasterTpmNonce_t[TPM_NONCE_SIZE_BYTES];

/**
* @brief Enum used for the getTPMs API to specify scope of TPMs to return
*/
Expand Down Expand Up @@ -250,17 +274,17 @@ namespace TRUSTEDBOOT
* be functional. All of these conditions must be met or an error
* log will result.
*
* @param[out] o_randNum A pointer to the array to be filled with random
* bits
*
* @param[in] i_randNumSize The desired size (bytes) of the random number
* to be requested from the TPM
*
* @param[out] o_randNum A pointer to the array 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,
uint8_t* o_randNum,
size_t i_randNumSize);
size_t i_randNumSize,
uint8_t* o_randNum);
#endif

/**
Expand Down Expand Up @@ -355,6 +379,49 @@ namespace TRUSTEDBOOT
*/
errlHndl_t flushTpmQueue();

/**
* @brief Send the command to the given TPM to create node attestation
* key pair
*
* @param[in] i_target the pointer to the TPM target to send the command to
* @return nullptr if success; non-nullptr on error
*/
errlHndl_t createAttestationKeys(TpmTarget* i_target);

/**
* @brief Send the command to the given TPM to retrieve the AK certificate
* from its NVRAM
*
* @param[in] i_target the pointer to the TPM target to send the command to
* @param[out] o_data the buffer to store the contents of AK certificate
* @return nullptr if success; non-nullptr on error
*/
errlHndl_t readAKCertificate(TpmTarget* i_target,
AKCertificate_t* o_data);

/**
* @brief Send the command to the given TPM to generate the quote
*
* @param[in] i_target the pointer to the TPM target to send the command to
* @param[in] i_masterNonce the 32-byte nonce from the master node
* @param[out] o_data a pointer to the data structure containing the size
* of the quote data from the TPM and the actual data
* @return nullptr if success; non-nullptr on error
*/
errlHndl_t generateQuote(TpmTarget* i_target,
MasterTpmNonce_t* i_masterNonce,
QuoteDataOut* o_data);

/**
* @brief Send the command to the given TPM to remove all context associated
* with created objects
*
* @param[in] i_target the pointer to the TPM target to send the command to
* @return nullptr if success; non-nullptr on error
*/
errlHndl_t flushContext(TpmTarget* i_target);


} // end TRUSTEDBOOT namespace


Expand Down
5 changes: 3 additions & 2 deletions src/usr/i2c/tpmdd.C
Original file line number Diff line number Diff line change
Expand Up @@ -2262,8 +2262,9 @@ errlHndl_t tpmPollForDataAvail( const tpm_info_t & i_tpmInfo)
tpm_sts_reg_t stsReg;
errlHndl_t err = NULL;

// Operation TIMEOUT_A defined by TCG spec for data available
for (size_t delay = 0; delay < TPMDD::TPM_TIMEOUT_A; delay += 10)
// Use the longer timeout B here since some of the TPM commands may take
// more than timeout A to complete
for (size_t delay = 0; delay < TPMDD::TPM_TIMEOUT_B; delay += 10)
{
err = tpmReadSTSRegValid(i_tpmInfo,
stsReg);
Expand Down
4 changes: 2 additions & 2 deletions src/usr/secureboot/node_comm/node_comm_exchange.C
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ errlHndl_t nodeCommAbusGetRandom(uint64_t & o_nonce)
// far if CONFIG_TPMDD wasn't set
#ifdef CONFIG_TPMDD
err = TRUSTEDBOOT::GetRandom(tpm_tgt,
reinterpret_cast<uint8_t*>(&o_nonce),
sizeof(o_nonce));
sizeof(o_nonce),
reinterpret_cast<uint8_t*>(&o_nonce));
#endif
if (err)
{
Expand Down
48 changes: 47 additions & 1 deletion src/usr/secureboot/trusted/base/trustedbootMsg.H
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <errl/errlentry.H>
#include <sys/msg.h>
#include "../trustedTypes.H"
#include <secureboot/trustedbootif.H>

namespace TRUSTEDBOOT
{
Expand All @@ -57,7 +58,11 @@ namespace TRUSTEDBOOT
MSG_TYPE_SHUTDOWN,
MSG_TYPE_INIT_BACKUP_TPM,
MSG_TYPE_GETRANDOM,
MSG_TYPE_LAST = MSG_TYPE_GETRANDOM,
MSG_TYPE_CREATE_ATT_KEYS,
MSG_TYPE_READ_AK_CERT,
MSG_TYPE_GEN_QUOTE,
MSG_TYPE_FLUSH_CONTEXT,
MSG_TYPE_LAST = MSG_TYPE_FLUSH_CONTEXT,
};

/// PCREXTEND message data
Expand All @@ -80,6 +85,47 @@ namespace TRUSTEDBOOT
uint8_t* o_randNum; // the random data is populated here
};

// Pure Target* cannot be sent as extra_data through a synchronous message
// because the act of deleting the sync mesage attempts to delete the ptr
// to the target as well, which causes hostboot crashes. This struct is
// a simple wrapper around the Target* for the messages requiring just the
// TPM target to be passed.
struct TpmTargetData
{
TpmTarget* tpm;
TpmTargetData(TpmTarget* i_tpm) :
tpm(i_tpm)
{
}
};

// The struct used to read the AK ceritificate from TPM's NVRAM
struct ReadAKCertData
{
TpmTarget* tpm;
AKCertificate_t* data; // The output of NVRAM read
ReadAKCertData(TpmTarget* i_tpm, AKCertificate_t* i_data) :
tpm(i_tpm), data(i_data)
{
}
};

// The struct used to generate TPM quote
struct GenQuoteData
{
TpmTarget* tpm;
MasterTpmNonce_t* masterNonce; // 32-byte nonce value
QuoteDataOut* data; // Output - the quote and signature fields
GenQuoteData(TpmTarget* i_tpm,
MasterTpmNonce_t* i_masterNonce,
QuoteDataOut* o_data) :
tpm(i_tpm),
masterNonce(i_masterNonce),
data(o_data)
{
}
};

// Trustedboot message class
class Message
{
Expand Down

0 comments on commit 868b68d

Please sign in to comment.