summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/secureboot/trustedboot_reasoncodes.H3
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C33
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H167
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.C85
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.H41
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C20
-rw-r--r--src/usr/secureboot/trusted/trustedboot.H15
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C182
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.H14
9 files changed, 539 insertions, 21 deletions
diff --git a/src/include/usr/secureboot/trustedboot_reasoncodes.H b/src/include/usr/secureboot/trustedboot_reasoncodes.H
index 77d237012..6cad6ebd7 100644
--- a/src/include/usr/secureboot/trustedboot_reasoncodes.H
+++ b/src/include/usr/secureboot/trustedboot_reasoncodes.H
@@ -50,6 +50,7 @@ namespace TRUSTEDBOOT
MOD_TPM_MARSHALCMDDATA = 0x04,
MOD_TPM_UNMARSHALRESPDATA = 0x05,
MOD_TPM_VERIFYFUNCTIONAL = 0x06,
+ MOD_TPM_CMD_PCREXTEND = 0x07,
MOD_TPMLOGMGR_INITIALIZE = 0x10,
MOD_TPMLOGMGR_ADDEVENT = 0x11,
@@ -73,6 +74,8 @@ namespace TRUSTEDBOOT
RC_TPMLOGMGR_ADDEVENTMARSH_FAIL = SECURE_COMP_ID | 0xAB,
RC_TPMLOGMGR_INIT_FAIL = SECURE_COMP_ID | 0xAC,
RC_TPM_NOFUNCTIONALTPM_FAIL = SECURE_COMP_ID | 0xAD,
+ RC_TPM_COMMAND_FAIL = SECURE_COMP_ID | 0xAE,
+ RC_TPM_INVALID_ARGS = SECURE_COMP_ID | 0xAF,
};
#ifdef __cplusplus
}
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index e9f20db59..dcd5a3191 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -43,6 +43,7 @@
#include <secureboot/trustedboot_reasoncodes.H>
#include "trustedboot_base.H"
#include "../trustedboot.H"
+#include "../trustedbootCmds.H"
#include "../trustedbootUtils.H"
#include "tpmLogMgr.H"
@@ -165,19 +166,7 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
}
}
-
-
- // If the TPM init has occurred and it is currently
- // functional we will do our extension
- if (io_target.available &&
- io_target.initAttempted &&
- !io_target.failed)
- {
-
- /// @todo RTC:125288 Add call to extend the PCR
- }
-
- // Now we log the event, we will do this in two scenarios
+ // Log the event, we will do this in two scenarios
// - !initAttempted - prior to IPL of the TPM we log for replay
// - initAttempted && !failed - TPM is functional so we log
if ((io_target.available &&
@@ -209,6 +198,24 @@ void pcrExtendSingleTpm(TpmTarget & io_target,
}
}
+ // If the TPM init has occurred and it is currently
+ // functional we will do our extension
+ if (io_target.available &&
+ io_target.initAttempted &&
+ !io_target.failed)
+ {
+
+ err = tpmCmdPcrExtend(&io_target,
+ i_pcr,
+ i_algId,
+ i_digest,
+ i_digestSize);
+ if (NULL != err)
+ {
+ break;
+ }
+ }
+
} while ( 0 );
if (NULL != err)
diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H
index 7b008ca5d..476b7e4c0 100755
--- a/src/usr/secureboot/trusted/test/trustedbootTest.H
+++ b/src/usr/secureboot/trusted/test/trustedbootTest.H
@@ -41,6 +41,8 @@
#include "../trustedTypes.H"
#include "../trustedboot.H"
#include "../trustedbootCmds.H"
+#include "../base/trustedboot_base.H"
+#include "../base/tpmLogMgr.H"
extern trace_desc_t* g_trac_trustedboot;
@@ -58,7 +60,6 @@ class TrustedBootTest: public CxxTest::TestSuite
{
public:
-
/**
* @brief Helper to run failing marshal tests
*/
@@ -378,6 +379,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Unsupported command
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandMarshal - Unsupported Command" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
baseCmd->commandCode = 0x12345;
@@ -393,6 +396,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Test 2ByteIn with Startup command
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandMarshal - 2ByteIn" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
TRUSTEDBOOT::TPM2_2ByteIn* cmdPtr =
@@ -411,6 +416,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Test GetCapabilityIn
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandMarshal - GetCapabilityIn" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
TRUSTEDBOOT::TPM2_GetCapabilityIn* cmdPtr =
@@ -428,6 +435,45 @@ class TrustedBootTest: public CxxTest::TestSuite
sizeof(TPM2_GetCapabilityIn));
}
+ // Test ExtendIn
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandMarshal - ExtendIn" );
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+ TRUSTEDBOOT::TPM2_ExtendIn* cmdPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_ExtendIn*>
+ (dataBufIn);
+ cmdPtr->base.tag = TPM_ST_SESSIONS;
+ cmdPtr->base.commandCode = TPM_CC_PCR_Extend;
+ cmdPtr->digests.count = 1;
+ cmdPtr->digests.digests[0].algorithmId = TPM_ALG_SHA256;
+
+ runTpmMarshalTest(baseCmd,
+ dataBufOut,
+ sizeof(dataBufOut),
+ cmdSize,
+ "ExtendIn",
+ num_ops,
+ fails,
+ sizeof(TPM2_ExtendIn) +
+ sizeof(TPMS_AUTH_COMMAND) +
+ 4); //auth size field
+
+ // Invalid number of digests
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+ cmdPtr->base.commandCode = TRUSTEDBOOT::TPM_CC_PCR_Extend;
+ cmdPtr->digests.count = HASH_COUNT+1;
+ runTpmMarshalFailTest(baseCmd,
+ dataBufOut,
+ sizeof(dataBufOut),
+ cmdSize,
+ "ExtendIn - invalid #digests",
+ num_ops,
+ fails);
+
+ }
} while( 0 );
@@ -455,6 +501,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Unsupported command
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandUnmarshal - Unsupported command" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
@@ -470,6 +518,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Test BaseOut with Startup command
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandUnmarshal - BaseOut" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
@@ -485,6 +535,8 @@ class TrustedBootTest: public CxxTest::TestSuite
// Test GetCapabilityOut
{
+ TRACUCOMP( g_trac_trustedboot,
+ "testCommandUnmarshal - GetCapabilityOut" );
memset(dataBufIn, 0, sizeof(dataBufIn));
memset(dataBufOut, 0, sizeof(dataBufOut));
@@ -517,6 +569,7 @@ class TrustedBootTest: public CxxTest::TestSuite
+
} while( 0 );
TRACFCOMP( g_trac_trustedboot,
"testCommandUnmarshal - End: %d/%d fails",
@@ -524,6 +577,118 @@ class TrustedBootTest: public CxxTest::TestSuite
}
+ /**
+ * @brief Retrieve a node target to test with
+ */
+ TRUSTEDBOOT::TpmTarget getTestTarget()
+ {
+ TARGETING::TargetService& tS = TARGETING::targetService();
+ TRUSTEDBOOT::TpmTarget target;
+ TPMDD::tpm_info_t tpmInfo;
+
+ target.available = true;
+ target.initAttempted = true;
+ target.failed = false;
+
+ tS.getMasterNodeTarget( target.nodeTarget );
+
+ assert(target.nodeTarget != NULL);
+
+ TRACFCOMP( g_trac_trustedboot,
+ "getTestTarget node tgt=0x%X chip=%d",
+ TARGETING::get_huid(target.nodeTarget));
+
+ // Let's see if the requested chip is functional
+ target.chip = TPMDD::TPM_PRIMARY;
+ tpmInfo.chip = TPMDD::TPM_PRIMARY;
+ errlHndl_t err = tpmReadAttributes (target.nodeTarget,
+ tpmInfo);
+
+ if (NULL != err)
+ {
+ target.failed = true;
+ delete err;
+ }
+ else if (!tpmInfo.tpmEnabled)
+ {
+ TRACFCOMP(g_trac_trustedboot, "getTestTarget - "
+ "Chip %d not enabled",
+ tpmInfo.chip);
+ target.failed = true;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_trustedboot, "getTestTarget - "
+ "Chip %d enabled",
+ target.chip);
+ }
+
+ return target;
+ }
+
+
+
+ /**
+ * @brief TPM Extend PCR
+ */
+ void testExtendPCR ( void )
+ {
+ int64_t fails = 0, num_ops = 0;
+ uint8_t digest[TPM_ALG_SHA256_SIZE];
+
+ TRACFCOMP( g_trac_trustedboot,
+ "testExtendPCR - Start" );
+ TpmTarget target = getTestTarget();
+
+ do
+ {
+
+ if (target.failed)
+ {
+ TS_FAIL( "testExtendPCR - Master TPM not functional" );
+ break;
+ }
+
+ for (size_t idx = 0; idx < sizeof(digest); idx++)
+ {
+ digest[idx] = idx+1;
+ }
+
+ for (size_t i = 0; i < 5; i ++) {
+
+ num_ops++;
+ pcrExtendSingleTpm(target,
+ PCR_DEBUG,
+ TPM_ALG_SHA256,
+ digest,
+ TPM_ALG_SHA256_SIZE,
+ "testExtendPCR - test 1");
+ if( target.failed )
+ {
+ fails++;
+ TS_FAIL( "testExtendPCR - Extend Error detected" );
+ break;
+ }
+ else
+ {
+ TRACUCOMP(g_trac_trustedboot, "testExtendPCR - "
+ "Extend returned as expected.");
+ }
+ }
+
+
+
+ } while( 0 );
+ TRACFCOMP( g_trac_trustedboot,
+ "testExtendPCR - End: %d/%d fails",
+ fails, num_ops );
+
+ if (NULL != target.logMgr)
+ {
+ delete target.logMgr;
+ }
+ }
+
};
diff --git a/src/usr/secureboot/trusted/trustedTypes.C b/src/usr/secureboot/trusted/trustedTypes.C
index f9ae71165..555efc141 100644
--- a/src/usr/secureboot/trusted/trustedTypes.C
+++ b/src/usr/secureboot/trusted/trustedTypes.C
@@ -136,6 +136,23 @@ namespace TRUSTEDBOOT
return NULL;
}
+ uint8_t* TPMT_HA_marshal(TPMT_HA* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->algorithmId), sizeof(val->algorithmId));
+ if (getDigestSize((TPM_Alg_Id)val->algorithmId) == 0)
+ {
+ return NULL;
+ }
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->digest.bytes),
+ getDigestSize((TPM_Alg_Id)val->algorithmId));
+ return o_tpmBuf;
+ }
+
size_t TCG_PCR_EVENT_marshalSize(TCG_PCR_EVENT* val)
{
return (sizeof(TCG_PCR_EVENT) + val->eventSize - MAX_TPM_LOG_MSG);
@@ -152,6 +169,35 @@ namespace TRUSTEDBOOT
return (sizeof(val->eventSize) + val->eventSize);
}
+
+ uint8_t* TPML_DIGEST_VALUES_marshal(TPML_DIGEST_VALUES* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t * io_cmdSize)
+ {
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->count), sizeof(val->count));
+ if (NULL != o_tpmBuf && HASH_COUNT < val->count)
+ {
+ o_tpmBuf = NULL;
+ }
+ else
+ {
+ for (size_t idx = 0; idx < val->count; idx++)
+ {
+ o_tpmBuf = TPMT_HA_marshal(&(val->digests[idx]),
+ o_tpmBuf,
+ i_tpmBufSize,
+ io_cmdSize);
+ if (NULL == o_tpmBuf)
+ {
+ break;
+ }
+ }
+ }
+ return o_tpmBuf;
+ }
+
uint8_t* TPM2_BaseIn_marshal(TPM2_BaseIn* val, uint8_t* o_tpmBuf,
size_t i_tpmBufSize, size_t* io_cmdSize)
{
@@ -180,6 +226,15 @@ namespace TRUSTEDBOOT
&(val->param), sizeof(val->param));
}
+ uint8_t* TPM2_4ByteIn_marshal(TPM2_4ByteIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->param), sizeof(val->param));
+ }
uint8_t* TPM2_GetCapabilityIn_marshal(TPM2_GetCapabilityIn* val,
uint8_t* o_tpmBuf,
@@ -218,6 +273,36 @@ namespace TRUSTEDBOOT
}
+ uint8_t* TPM2_ExtendIn_marshalHandle(TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base has already been marshaled
+ // only marshal the pcr handle in this stage
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &(val->pcrHandle), sizeof(val->pcrHandle));
+ }
+
+ uint8_t* TPM2_ExtendIn_marshalParms(TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ // Base and handle has already been marshaled
+ return (TPML_DIGEST_VALUES_marshal(&(val->digests), o_tpmBuf,
+ i_tpmBufSize, io_cmdSize));
+ }
+
+
+ uint8_t* TPMS_AUTH_COMMAND_marshal(TPMS_AUTH_COMMAND* val,
+ uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t* io_cmdSize)
+ {
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ val, sizeof(TPMS_AUTH_COMMAND));
+ }
#ifdef __cplusplus
} // end TRUSTEDBOOT
diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H
index f6348f6bb..d3f98dec0 100644
--- a/src/usr/secureboot/trusted/trustedTypes.H
+++ b/src/usr/secureboot/trusted/trustedTypes.H
@@ -41,6 +41,7 @@
#include <stdint.h>
#ifdef __HOSTBOOT_MODULE
#include <builtins.h>
+#include <secureboot/trustedbootif.H>
#else
#include "trustedboot.H"
#define PACKED __attribute__((__packed__))
@@ -77,6 +78,7 @@ namespace TRUSTEDBOOT
MAX_TPM_LOG_MSG = 128, ///< Maximum log message size
HASH_COUNT = 1, ///< Maximum # of digests
+ PCR_SELECT_MAX = ((PCR_MAX+7)/8), ///< PCR selection octet max
};
typedef enum
@@ -134,6 +136,10 @@ namespace TRUSTEDBOOT
TPM_RC_INITIALIZE = 0x100,
+
+ // TPM Authorization types
+ TPM_RS_PW = 0x40000009,
+
};
@@ -208,6 +214,8 @@ namespace TRUSTEDBOOT
typedef struct _TPMT_HA TPMT_HA;
size_t TPMT_HA_marshalSize(TPMT_HA* val);
uint8_t* TPMT_HA_logMarshal(TPMT_HA* val, uint8_t* i_logBuf);
+ uint8_t* TPMT_HA_marshal(TPMT_HA* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t * io_cmdSize);
/// Crypto agile digests list
@@ -220,6 +228,9 @@ namespace TRUSTEDBOOT
size_t TPML_DIGEST_VALUES_marshalSize(TPML_DIGEST_VALUES* val);
uint8_t* TPML_DIGEST_VALUES_logMarshal(TPML_DIGEST_VALUES* val,
uint8_t* i_logBuf);
+ uint8_t* TPML_DIGEST_VALUES_marshal(TPML_DIGEST_VALUES* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t * io_cmdSize);
/// Event field structure
struct _TPM_EVENT_FIELD
@@ -276,6 +287,16 @@ namespace TRUSTEDBOOT
uint8_t* TPM2_2ByteIn_marshal(TPM2_2ByteIn* val, uint8_t* o_tpmBuf,
size_t i_tpmBufSize, size_t* io_cmdSize);
+ /// Generic TPM Input Command structure with a 4 byte param
+ struct _TPM2_4ByteIn
+ {
+ TPM2_BaseIn base;
+ uint32_t param;
+ } PACKED;
+ typedef struct _TPM2_4ByteIn TPM2_4ByteIn;
+ uint8_t* TPM2_4ByteIn_marshal(TPM2_4ByteIn* val, uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize, size_t* io_cmdSize);
+
/// Generic TPM Output Command structure with a 4 byte return data
struct _TPM2_4ByteOut
@@ -320,6 +341,26 @@ namespace TRUSTEDBOOT
TPML_DIGEST_VALUES digests; ///< Values to be extended
} PACKED;
typedef struct _TPM2_ExtendIn TPM2_ExtendIn;
+ uint8_t* TPM2_ExtendIn_marshalHandle(TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+ uint8_t* TPM2_ExtendIn_marshalParms(TPM2_ExtendIn* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
+
+ /// TPM Authorization structure
+ /// This is not the full structure and only works for PW auth with NULL PW
+ struct _TPMS_AUTH_COMMAND
+ {
+ uint32_t sessionHandle;
+ uint16_t nonceSize; ///< Size of nonce structure, currently 0
+ uint8_t sessionAttributes; ///< Session attributes
+ uint16_t hmacSize; ///< Size of hmac structure, currently 0
+ } PACKED;
+ typedef struct _TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND;
+ uint8_t* TPMS_AUTH_COMMAND_marshal(TPMS_AUTH_COMMAND* val,
+ uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t* io_cmdSize);
#ifdef __cplusplus
} // end TRUSTEDBOOT namespace
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index ad596648c..d51c9e031 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -112,6 +112,9 @@ void* host_update_master_tpm( void *io_pArgs )
}
}
+ // Now we need to replay any existing entries in the log into the TPM
+ tpmReplayLog(systemTpms.tpm[TPM_MASTER_INDEX]);
+
if (systemTpms.tpm[TPM_MASTER_INDEX].failed ||
!systemTpms.tpm[TPM_MASTER_INDEX].available)
{
@@ -150,6 +153,15 @@ void* host_update_master_tpm( void *io_pArgs )
err = TPMDD::tpmReadAttributes(nodeTarget, tpmInfo);
if (NULL != err)
{
+ // We don't want to log this error we will just assume
+ // the backup doesn't exist
+ delete err;
+ err = NULL;
+ TRACUCOMP( g_trac_trustedboot,
+ "host_update_master_tpm() tgt=0x%X "
+ "Marking backup TPM unavailable due to attribute fail",
+ TARGETING::get_huid(nodeTarget));
+ systemTpms.tpm[TPM_BACKUP_INDEX].available = false;
break;
}
else if (!tpmInfo.tpmEnabled)
@@ -228,7 +240,15 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
TRACDCOMP( g_trac_trustedboot,
EXIT_MRK"tpmInitialize()");
+}
+void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target)
+{
+ ///@todo RTC:125288 Implement replay
+ // Function will walk existing entries in the TPM log and call
+ // tpmCmdPcrExtend as required
+ // This function must commit any errors and call tpmMarkFailed if errors
+ // are found
}
diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H
index eaf950759..2569de487 100644
--- a/src/usr/secureboot/trusted/trustedboot.H
+++ b/src/usr/secureboot/trusted/trustedboot.H
@@ -65,7 +65,7 @@ public:
/**
- * @brief Initialize the targetted TPM
+ * @brief Initialize the targeted TPM
* @param[in/out] io_target Current TPM target structure
* @param[in] i_nodeTarget Node Target
* @param[in] i_chip Chip to initialize
@@ -74,6 +74,19 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
TARGETING::Target* i_nodeTarget,
TPMDD::tpm_chip_types_t i_chip);
+/**
+ * @brief Verify a functional TPM still exists in the system
+ * @return errlHndl_t NULL if TPM available, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t tpmVerifyFunctionalTpmExists();
+
+/**
+ * @brief Replay the entries that exist in the log into the TPM as needed
+ * @param[in/out] io_target Current TPM target structure
+ */
+void tpmReplayLog(TRUSTEDBOOT::TpmTarget & io_target);
+
} // end TRUSTEDBOOT namespace
#endif
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
index aa5d713fa..611708c2e 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.C
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -120,9 +120,13 @@ errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
{
errlHndl_t err = TB_SUCCESS;
uint8_t* sBuf = o_outbuf;
+ uint32_t* sSizePtr = NULL;
+ size_t curSize = 0;
int stage = 0;
TPM2_BaseIn* baseCmd =
(TPM2_BaseIn*)o_outbuf;
+ TPMS_AUTH_COMMAND cmdAuth;
+
*o_cmdSize = 0;
TRACDCOMP( g_trac_trustedboot,
@@ -142,19 +146,55 @@ errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
break;
}
-
// Marshal the handles
stage = 1;
-
+ if (TPM_CC_PCR_Extend == i_cmd->commandCode)
+ {
+ TPM2_ExtendIn* cmdPtr = (TPM2_ExtendIn*)i_cmd;
+ sBuf = TPM2_ExtendIn_marshalHandle(cmdPtr,
+ sBuf,
+ i_bufsize,
+ o_cmdSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+ }
// Marshal the authorizations
stage = 2;
+ if (TPM_CC_PCR_Extend == i_cmd->commandCode)
+ {
+ // Insert a password authorization with a null pw
+ // Make room for the 4 byte size field at the beginning
+ sSizePtr = (uint32_t*)sBuf;
+ sBuf += sizeof(uint32_t);
+ *o_cmdSize += sizeof(uint32_t);
+ i_bufsize -= sizeof(uint32_t);
+ curSize = *o_cmdSize;
+
+ cmdAuth.sessionHandle = TPM_RS_PW;
+ cmdAuth.nonceSize = 0;
+ cmdAuth.sessionAttributes = 0;
+ cmdAuth.hmacSize = 0;
+
+ sBuf = TPMS_AUTH_COMMAND_marshal(&cmdAuth, sBuf, i_bufsize,
+ o_cmdSize);
+
+ if (NULL == sBuf)
+ {
+ break;
+ }
+ // Put in the size of the auth area
+ *sSizePtr = (*o_cmdSize - curSize);
- // Marshal the parameters
+ }
+
+ // Marshal the command parameters
stage = 3;
switch (i_cmd->commandCode)
{
- // Two byte parm fields
+ // Two byte parm fields
case TPM_CC_Startup:
{
TPM2_2ByteIn* cmdPtr =
@@ -172,6 +212,13 @@ errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
i_bufsize, o_cmdSize);
}
break;
+ case TPM_CC_PCR_Extend:
+ {
+ TPM2_ExtendIn* cmdPtr = (TPM2_ExtendIn*)i_cmd;
+ sBuf = TPM2_ExtendIn_marshalParms(cmdPtr, sBuf,
+ i_bufsize, o_cmdSize);
+ }
+ break;
default:
{
@@ -197,11 +244,19 @@ errlHndl_t tpmMarshalCommandData(TPM2_BaseIn* i_cmd,
break;
};
- if (TB_SUCCESS != err)
+ if (TB_SUCCESS != err || NULL == sBuf)
{
break;
}
+ // Do a verification that the cmdSize equals what we used
+ if (((size_t)(sBuf - o_outbuf)) != *o_cmdSize)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL MARSHAL SIZE MISMATCH : %d %d",
+ (sBuf - o_outbuf), *o_cmdSize );
+ sBuf = NULL;
+ }
// Lastly now that we know the size update the byte stream
baseCmd->commandSize = *o_cmdSize;
@@ -285,8 +340,9 @@ errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
stage = 2;
switch (i_commandCode)
{
- // Empty response commands
+ // Empty response commands
case TPM_CC_Startup:
+ case TPM_CC_PCR_Extend:
// Nothing to do
break;
@@ -645,6 +701,120 @@ errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target)
}
+errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* i_digest,
+ size_t i_digestSize)
+{
+ errlHndl_t err = NULL;
+ uint8_t dataBuf[sizeof(TPM2_ExtendIn)];
+ size_t dataSize = sizeof(dataBuf);
+ size_t fullDigestSize = 0;
+ TPM2_BaseOut* resp = (TPM2_BaseOut*)dataBuf;
+ TPM2_ExtendIn* cmd = (TPM2_ExtendIn*)dataBuf;
+
+
+ TRACDCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrExtend()" );
+ TRACUCOMP( g_trac_trustedboot,
+ ">>tpmCmdPcrExtend() Pcr(%d) Alg(%X) DS(%d)",
+ i_pcr, i_algId, (int)i_digestSize);
+
+ do
+ {
+
+ fullDigestSize = getDigestSize(i_algId);
+
+ // Build our command block
+ memset(dataBuf, 0, sizeof(dataBuf));
+
+ // Argument verification
+ if (fullDigestSize == 0 ||
+ fullDigestSize != i_digestSize ||
+ NULL == i_digest ||
+ PCR_MAX < i_pcr
+ )
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCR EXTEND ARG FAILURE FDS(%d) DS(%d) PCR(%d)",
+ (int)fullDigestSize, (int)i_digestSize, i_pcr);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_INVALID_ARGS
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCREXTEND
+ * @userdata1 Digest Ptr
+ * @userdata2[0:31] Full Digest Size
+ * @userdata2[32:63] PCR
+ * @devdesc Unmarshaling error detected
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCREXTEND,
+ RC_TPM_INVALID_ARGS,
+ (uint64_t)i_digest,
+ (fullDigestSize << 32) |
+ i_pcr);
+ break;
+ }
+
+ // Log the input PCR value
+ TRACUBIN(g_trac_trustedboot, "PCR In",
+ i_digest, fullDigestSize);
+
+ cmd->base.tag = TPM_ST_SESSIONS;
+ cmd->base.commandCode = TPM_CC_PCR_Extend;
+ cmd->pcrHandle = i_pcr;
+ cmd->digests.count = 1;
+ cmd->digests.digests[0].algorithmId = i_algId;
+ memcpy(cmd->digests.digests[0].digest.bytes, i_digest, fullDigestSize);
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (TB_SUCCESS != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRExtend Transmit Fail");
+ break;
+
+ }
+ else if ((sizeof(TPM2_BaseOut) > dataSize)
+ || (TPM_SUCCESS != resp->responseCode))
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM PCRExtend OP Fail Ret(%X) ExSize(%d) Size(%d) ",
+ resp->responseCode,
+ (int)sizeof(TPM2_BaseOut),
+ (int)dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_COMMAND_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_PCREXTEND
+ * @userdata1 responseCode
+ * @userdata2 dataSize
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = tpmCreateErrorLog(MOD_TPM_CMD_PCREXTEND,
+ RC_TPM_COMMAND_FAIL,
+ resp->responseCode,
+ dataSize);
+ break;
+
+ }
+
+ } while ( 0 );
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ "<<tpmCmdPcrExtend() - %s",
+ ((TB_SUCCESS == err) ? "No Error" : "With Error") );
+ return err;
+
+}
+
#ifdef __cplusplus
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.H b/src/usr/secureboot/trusted/trustedbootCmds.H
index 0965b1401..8b68e23c4 100644
--- a/src/usr/secureboot/trusted/trustedbootCmds.H
+++ b/src/usr/secureboot/trusted/trustedbootCmds.H
@@ -112,6 +112,20 @@ errlHndl_t tpmCmdStartup(TpmTarget* io_target);
errlHndl_t tpmCmdGetCapFwVersion(TpmTarget* io_target);
+/**
+ * @brief Send the TPM_Extend command to the targeted TPM and log
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in] i_pcr PCR to write to
+ * @param[in] i_algId Algorithm to use
+ * @param[in] i_digest Digest value to write to PCR, zeros appended as needed
+ * @param[in] i_digestSize Byte size of i_digest array
+ */
+errlHndl_t tpmCmdPcrExtend(TpmTarget * io_target,
+ TPM_Pcr i_pcr,
+ TPM_Alg_Id i_algId,
+ uint8_t* i_digest,
+ size_t i_digestSize);
+
#ifdef __cplusplus
} // end TRUSTEDBOOT namespace
OpenPOWER on IntegriCloud