summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Engel <cjengel@us.ibm.com>2015-08-03 16:01:14 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-12-11 11:17:32 -0600
commite914974751a5125cff6fa7078399db6f3aac5641 (patch)
tree4f50b6677a2a0111f98884813ff7e028459bcca2
parent0cbd52585b9013430efeaeed6b4c38f6122eea98 (diff)
downloadtalos-hostboot-e914974751a5125cff6fa7078399db6f3aac5641.tar.gz
talos-hostboot-e914974751a5125cff6fa7078399db6f3aac5641.zip
Trustedboot: Additional commands in trusted boot init sequence
- getCap FW Version - TPM Command marshal/unmarshal code Change-Id: Ia9a90b1160c9c3b5d818318771bff21eb013bdf4 RTC: 125287 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/20056 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com> Reviewed-by: Timothy R. Block <block@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/i2c/tpmddif.H46
-rw-r--r--src/include/usr/secureboot/trustedboot_reasoncodes.H14
-rw-r--r--src/include/usr/secureboot/trustedbootif.H5
-rw-r--r--src/makefile1
-rwxr-xr-xsrc/usr/i2c/test/tpmddtest.H98
-rwxr-xr-xsrc/usr/i2c/tpmdd.C46
-rwxr-xr-xsrc/usr/i2c/tpmdd.H44
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C1
-rw-r--r--src/usr/secureboot/trusted/makefile4
-rw-r--r--src/usr/secureboot/trusted/test/makefile30
-rwxr-xr-xsrc/usr/secureboot/trusted/test/trustedbootTest.H529
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.C219
-rw-r--r--src/usr/secureboot/trusted/trustedTypes.H297
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C110
-rw-r--r--src/usr/secureboot/trusted/trustedboot.H147
-rw-r--r--src/usr/secureboot/trusted/trustedbootCmds.C717
16 files changed, 1999 insertions, 309 deletions
diff --git a/src/include/usr/i2c/tpmddif.H b/src/include/usr/i2c/tpmddif.H
index 0a8233eda..08fbebfc0 100644
--- a/src/include/usr/i2c/tpmddif.H
+++ b/src/include/usr/i2c/tpmddif.H
@@ -51,6 +51,35 @@ enum tpm_op_types_t
};
/**
+* @brief Enumerations to describe the type of devices to be accessed.
+*/
+enum tpm_addr_size_t
+{
+ ONE_BYTE_ADDR = 1,
+ TWO_BYTE_ADDR = 2,
+ LAST_DEVICE_TYPE
+};
+
+/**
+ * @brief Structure of common parameters needed by different parts of
+ * the code.
+ */
+struct tpm_info_t
+{
+ tpm_op_types_t operation; ///< TPM operation to perform
+ TARGETING::EntityPath i2cMasterPath; ///< I2C Master path
+ TARGETING::Target * i2cTarget; ///< I2C Target
+
+ uint8_t port; ///< I2C Master port
+ uint8_t engine; ///< I2C Master engine
+ uint8_t chip; ///< Chip target, primary/backup
+ uint8_t tpmEnabled; ///< TPM attribute defined as available
+ uint8_t devAddr; ///< I2C Address
+ size_t offset; ///< TPM Device register offset
+ tpm_addr_size_t addrSize; ///< I2C Addr size
+};
+
+/**
*
* @brief Determine if targeted TPM is present and enabled in the system
*
@@ -63,6 +92,23 @@ enum tpm_op_types_t
bool tpmPresence ( TARGETING::Target * i_target,
tpm_chip_types_t i_chip );
+/**
+ * @brief this function will read all of the associated attributes needed
+ * to access the intended TPM. These attributes will be used to
+ * determine the type of I2C device as well as how to address it via
+ * the I2C device driver.
+ *
+ * @param[in] i_target target node.
+ *
+ * @param[in/out] io_tpmInfo The structure that will contain the attribute data
+ * read from the target device. Chip field must be set
+ *
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmReadAttributes ( TARGETING::Target * i_target,
+ tpm_info_t & io_tpmInfo );
+
}; // end namespace TPMDD
diff --git a/src/include/usr/secureboot/trustedboot_reasoncodes.H b/src/include/usr/secureboot/trustedboot_reasoncodes.H
index 53fb6f8fc..4ee9a16e1 100644
--- a/src/include/usr/secureboot/trustedboot_reasoncodes.H
+++ b/src/include/usr/secureboot/trustedboot_reasoncodes.H
@@ -33,7 +33,11 @@ namespace TRUSTEDBOOT
{
MOD_HOST_UPDATE_MASTER_TPM = 0x00,
MOD_TPM_INITIALIZE = 0x01,
- };
+ MOD_TPM_CMD_STARTUP = 0x02,
+ MOD_TPM_CMD_GETCAPFWVERSION = 0x03,
+ MOD_TPM_MARSHALCMDDATA = 0x04,
+ MOD_TPM_UNMARSHALRESPDATA = 0x05,
+ };
enum TRUSTEDReasonCode
{
@@ -41,6 +45,14 @@ namespace TRUSTEDBOOT
RC_TPM_START_FAIL = SECURE_COMP_ID | 0xA0,
RC_TPM_EXISTENCE_FAIL = SECURE_COMP_ID | 0xA1,
+ RC_TPM_GETCAP_FAIL = SECURE_COMP_ID | 0xA2,
+ RC_TPM_GETCAP_FW_INVALID_RESP = SECURE_COMP_ID | 0xA3,
+ RC_TPM_GETCAP2_FAIL = SECURE_COMP_ID | 0xA4,
+ RC_TPM_GETCAP2_FW_INVALID_RESP = SECURE_COMP_ID | 0xA5,
+ RC_TPM_MARSHAL_INVALID_CMD = SECURE_COMP_ID | 0xA6,
+ RC_TPM_MARSHALING_FAIL = SECURE_COMP_ID | 0xA7,
+ RC_TPM_UNMARSHAL_INVALID_CMD = SECURE_COMP_ID | 0xA8,
+ RC_TPM_UNMARSHALING_FAIL = SECURE_COMP_ID | 0xA9,
};
}
diff --git a/src/include/usr/secureboot/trustedbootif.H b/src/include/usr/secureboot/trustedbootif.H
index d59cd1e14..dea32b959 100644
--- a/src/include/usr/secureboot/trustedbootif.H
+++ b/src/include/usr/secureboot/trustedbootif.H
@@ -45,13 +45,14 @@ namespace TRUSTEDBOOT
TARGETING::Target* nodeTarget; ///< Node target ptr
TPMDD::tpm_chip_types_t chip; ///< Chip Pri vs Backup
uint8_t initAttempted:1;///< Has TPM init been run
+ uint8_t available:1; ///< Is TPM physically in system
uint8_t failed:1; ///< Is TPM currently failed
mutex_t tpmMutex; ///< TPM Mutex
TpmTarget();
};
- /// TPM PCR designations
+ /// TPM PCR designations
enum TPM_Pcr
{
PCR_0 = 0,
@@ -73,7 +74,7 @@ namespace TRUSTEDBOOT
void* host_update_master_tpm( void *io_pArgs );
/**
- * @brief Extend a measurement into the TPMs and log
+ * @brief Extend a measurement into the TPMs and log atomically
* @param[in] i_pcr PCR to write to
* @param[in] i_digest Digest value to write to PCR
* @param[in] i_digestSize Byte size of i_digest data
diff --git a/src/makefile b/src/makefile
index f581ebafb..ec511c80d 100644
--- a/src/makefile
+++ b/src/makefile
@@ -204,6 +204,7 @@ TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testruntime)
TESTCASE_MODULES += testibscom
TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testdump)
TESTCASE_MODULES += $(if $(CONFIG_VPO_COMPILE),,testsecureboot)
+TESTCASE_MODULES += $(if $(CONFIG_TPMDD),testtrusted)
TESTCASE_MODULES += testfsiscom
TESTCASE_MODULES += testrtloader
TESTCASE_MODULES += testsbe
diff --git a/src/usr/i2c/test/tpmddtest.H b/src/usr/i2c/test/tpmddtest.H
index 74f71b28e..4053245a6 100755
--- a/src/usr/i2c/test/tpmddtest.H
+++ b/src/usr/i2c/test/tpmddtest.H
@@ -38,9 +38,10 @@
#include <devicefw/driverif.H>
#include <i2c/tpmddreasoncodes.H>
#include <targeting/common/commontargeting.H>
+#include "secureboot/trustedbootif.H"
#include "i2ctest.H"
#include "../tpmdd.H"
-#include "../../secureboot/trusted/trustedboot.H"
+#include "../../secureboot/trusted/trustedTypes.H"
extern trace_desc_t* g_trac_tpmdd;
@@ -541,16 +542,16 @@ class TPMDDTest: public CxxTest::TestSuite
memset(data, 0xFE, sizeof(data));
TRUSTEDBOOT::TPM2_GetCapabilityIn* cmd =
- (TRUSTEDBOOT::TPM2_GetCapabilityIn*)data;
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityIn*>
+ (data);
- cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
cmd->base.commandSize =
sizeof (TRUSTEDBOOT::TPM2_GetCapabilityIn);
+ cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
cmd->capability = TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
cmd->property = TRUSTEDBOOT::TPM_PT_MANUFACTURER;
cmd->propertyCount = 1;
-
cmdSize = cmd->base.commandSize;
num_ops++;
@@ -623,97 +624,12 @@ class TPMDDTest: public CxxTest::TestSuite
continue;
}
- // Build our command block for a startup
- memset(data, 0xFE, sizeof(data));
-
- // Test a TPM command underflow
- TRUSTEDBOOT::TPM2_GetCapabilityIn* cmd =
- (TRUSTEDBOOT::TPM2_GetCapabilityIn*)data;
-
- cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
- cmd->base.commandSize =
- sizeof (TRUSTEDBOOT::TPM2_GetCapabilityIn);
- cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
- cmd->capability = TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
- cmd->property = TRUSTEDBOOT::TPM_PT_MANUFACTURER;
- cmd->propertyCount = 1;
-
- cmdSize = cmd->base.commandSize;
-
- num_ops++;
- err = deviceRead(testTarget,
- &data,
- dataSize,
- DEVICE_TPM_ADDRESS( TPM_PRIMARY,
- TPM_OP_TRANSMIT,
- cmdSize - 1) );
-
- if( NULL == err ||
- err->reasonCode() != TPM_UNDERFLOW_ERROR)
- {
- fails++;
- TS_FAIL( "testTPMTransmitOverUnder - Error "
- "command underflow not detected" );
- errlCommit( err,
- TPMDD_COMP_ID );
- delete err;
- err = NULL;
- }
- else
- {
- TRACUCOMP(g_trac_tpmdd, "testTPMTransmitOverUnder - "
- "CmdUnder Transmit returned as expected. len=%d",
- dataSize);
- }
-
-
- // Build our command block for a startup
- dataSize = sizeof(data);
- memset(data, 0xFE, sizeof(data));
-
- // Test a TPM command overflow
-
- cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
- cmd->base.commandSize =
- sizeof (TRUSTEDBOOT::TPM2_GetCapabilityIn);
- cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
- cmd->capability = TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
- cmd->property = TRUSTEDBOOT::TPM_PT_MANUFACTURER;
- cmd->propertyCount = 1;
-
- cmdSize = cmd->base.commandSize;
-
- num_ops++;
- err = deviceRead(testTarget,
- &data,
- dataSize,
- DEVICE_TPM_ADDRESS( TPM_PRIMARY,
- TPM_OP_TRANSMIT,
- cmdSize + 1) );
-
- if( NULL == err ||
- err->reasonCode() != TPM_OVERFLOW_ERROR)
- {
- fails++;
- TS_FAIL( "testTPMTransmitOverUnder - Error "
- "command overflow not detected" );
- errlCommit( err,
- TPMDD_COMP_ID );
- delete err;
- err = NULL;
- }
- else
- {
- TRACUCOMP(g_trac_tpmdd, "testTPMTransmitOverUnder - "
- "CmdOver Transmit returned as expected. len=%d",
- dataSize);
- }
-
- // Build our command block for a startup
dataSize = sizeof(data);
memset(data, 0xFE, sizeof(data));
// Test a TPM data overflow
+ TRUSTEDBOOT::TPM2_GetCapabilityIn* cmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityIn*>(data);
cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
cmd->base.commandSize =
diff --git a/src/usr/i2c/tpmdd.C b/src/usr/i2c/tpmdd.C
index 16748c4b3..ef34ba2b7 100755
--- a/src/usr/i2c/tpmdd.C
+++ b/src/usr/i2c/tpmdd.C
@@ -154,16 +154,6 @@ errlHndl_t tpmPerformOp( DeviceFW::OperationType i_opType,
- // Get i2c master target
- err = tpmGetI2CMasterTarget( i_target,
- tpmInfo );
-
- if( err )
- {
- break;
- }
-
-
// Lock to sequence operations
mutex_lock( &g_tpmMutex );
unlock = true;
@@ -326,21 +316,6 @@ bool tpmPresence ( TARGETING::Target * i_target,
break;
}
- // Get i2c master target
- err = tpmGetI2CMasterTarget( i_target,
- tpmInfo );
-
- if( err )
- {
- TRACFCOMP(g_trac_tpmdd,
- ERR_MRK"Error in tpmPresence::tpmGetI2Cmaster() "
- "RC 0x%X", err->reasonCode());
- l_present = false;
- delete err;
- err = NULL;
- break;
- }
-
// Ensure the TPM is enabled
if (!tpmInfo.tpmEnabled)
{
@@ -1267,6 +1242,19 @@ errlHndl_t tpmReadAttributes ( TARGETING::Target * i_target,
}
+ // Get i2c master target
+ err = tpmGetI2CMasterTarget( i_target,
+ io_tpmInfo );
+
+ if( err )
+ {
+ TRACFCOMP(g_trac_tpmdd,
+ ERR_MRK"Error in tpmReadAttributes::tpmGetI2Cmaster() "
+ "RC 0x%X", err->reasonCode());
+ break;
+ }
+
+
} while( 0 );
TRACUCOMP(g_trac_tpmdd,"tpmReadAttributes() tgt=0x%X, %d/%d/0x%X "
@@ -1320,9 +1308,9 @@ errlHndl_t tpmGetI2CMasterTarget ( TARGETING::Target * i_target,
{
// Path element: type:8 instance:8
l_epCompressed |=
- io_tpmInfo.i2cMasterPath[i].type << (16*(3-i));
+ io_tpmInfo.i2cMasterPath[i].type << ((16*(3-i))+8);
l_epCompressed |=
- io_tpmInfo.i2cMasterPath[i].instance << ((16*(3-i))-8);
+ io_tpmInfo.i2cMasterPath[i].instance << (16*(3-i));
// Can only fit 4 path elements into 64 bits
if ( i == 3 )
@@ -1374,9 +1362,9 @@ errlHndl_t tpmGetI2CMasterTarget ( TARGETING::Target * i_target,
{
// Path element: type:8 instance:8
l_epCompressed |=
- io_tpmInfo.i2cMasterPath[i].type << (16*(3-i));
+ io_tpmInfo.i2cMasterPath[i].type << ((16*(3-i))+8);
l_epCompressed |=
- io_tpmInfo.i2cMasterPath[i].instance << ((16*(3-i))-8);
+ io_tpmInfo.i2cMasterPath[i].instance << (16*(3-i));
// Can only fit 4 path elements into 64 bits
if ( i == 3 )
diff --git a/src/usr/i2c/tpmdd.H b/src/usr/i2c/tpmdd.H
index c81e436d4..ad531d67d 100755
--- a/src/usr/i2c/tpmdd.H
+++ b/src/usr/i2c/tpmdd.H
@@ -41,15 +41,6 @@
namespace TPMDD
{
-/**
-* @brief Enumerations to describe the type of devices to be accessed.
-*/
-enum tpm_addr_size_t
-{
- ONE_BYTE_ADDR = 1,
- TWO_BYTE_ADDR = 2,
- LAST_DEVICE_TYPE
-};
/// TPM Timeouts listed in ms
/// Timeout names and durations are as described in the TCG specification
@@ -67,24 +58,6 @@ enum
MAX_STSVALID_POLLS = 5, ///< Max poll of 50ms (5*10ms)
};
-/**
- * @brief Structure of common parameters needed by different parts of
- * the code.
- */
-struct tpm_info_t
-{
- tpm_op_types_t operation; ///< TPM operation to perform
- uint64_t port; ///< I2C Master port
- uint64_t engine; ///< I2C Master engin
- tpm_addr_size_t addrSize; ///< I2C Addr size
- TARGETING::EntityPath i2cMasterPath; ///< I2C Master path
- TARGETING::Target * i2cTarget; ///< I2C Target
-
- uint8_t chip; ///< Chip target, primary/backup
- uint8_t tpmEnabled; ///< Is this TPM available and functional?
- uint8_t devAddr; ///< I2C Address
- size_t offset; ///< TPM Device register offset
-};
@@ -257,23 +230,6 @@ errlHndl_t tpmPrepareAddress ( void * io_buffer,
tpm_info_t i_tpmInfo );
/**
- * @brief this function will read all of the associated attributes needed
- * to access the intended TPM. These attributes will be used to
- * determine the type of I2C device as well as how to address it via
- * the I2C device driver.
- *
- * @param[in] i_target target node.
- *
- * @param[in/out] io_tpmInfo The structure that will contain the attribute data
- * read from the target device.
- *
- * @return errlHndl_t NULL if successful, otherwise a pointer to the
- * error log.
- */
-errlHndl_t tpmReadAttributes ( TARGETING::Target * i_target,
- tpm_info_t & io_tpmInfo );
-
-/**
* @brief This function decides whether or not the target passed into the
* TPM device driver actually contains the I2C Master engines. If
* not, it will then read the attribute of the target to get the path
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 95a55fdc2..d7d3295cb 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -65,6 +65,7 @@ SystemTpms::SystemTpms()
TpmTarget::TpmTarget()
{
memset(this, 0, sizeof(TpmTarget));
+ available = true; // Default to available until we know better
mutex_init(&tpmMutex);
}
diff --git a/src/usr/secureboot/trusted/makefile b/src/usr/secureboot/trusted/makefile
index 00991ed0f..fec117924 100644
--- a/src/usr/secureboot/trusted/makefile
+++ b/src/usr/secureboot/trusted/makefile
@@ -26,6 +26,10 @@ ROOTPATH = ../../../..
MODULE = secureboot_trusted
OBJS += $(if $(CONFIG_TPMDD),trustedboot.o,)
+OBJS += $(if $(CONFIG_TPMDD),trustedbootCmds.o,)
+OBJS += $(if $(CONFIG_TPMDD),trustedTypes.o,)
+
+SUBDIRS += $(if $(CONFIG_TPMDD),test.d,)
CFLAGS += -iquote ../
include ${ROOTPATH}/config.mk
diff --git a/src/usr/secureboot/trusted/test/makefile b/src/usr/secureboot/trusted/test/makefile
new file mode 100644
index 000000000..3345252a6
--- /dev/null
+++ b/src/usr/secureboot/trusted/test/makefile
@@ -0,0 +1,30 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/secureboot/trusted/test/makefile $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2015
+# [+] 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
+ROOTPATH = ../../../../..
+
+MODULE = testtrusted
+TESTS += $(if $(CONFIG_TPMDD),trustedbootTest.H,)
+
+include ${ROOTPATH}/config.mk \ No newline at end of file
diff --git a/src/usr/secureboot/trusted/test/trustedbootTest.H b/src/usr/secureboot/trusted/test/trustedbootTest.H
new file mode 100755
index 000000000..de2a2d8ed
--- /dev/null
+++ b/src/usr/secureboot/trusted/test/trustedbootTest.H
@@ -0,0 +1,529 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/test/trustedbootTest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 */
+#ifndef __TRUSTEDBOOTTEST_H
+#define __TRUSTEDBOOTTEST_H
+
+/**
+ * @file trustedbootTest.H
+ *
+ * @brief Test cases for trustedboot
+ */
+
+#include <sys/time.h>
+#include <cxxtest/TestSuite.H>
+#include <targeting/common/commontargeting.H>
+#include <errl/errlmanager.H>
+#include <errl/errlentry.H>
+#include <i2c/tpmddif.H>
+#include <secureboot/trustedbootif.H>
+#include "../trustedTypes.H"
+#include "../trustedboot.H"
+
+extern trace_desc_t* g_trac_trustedboot;
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+//#define TRACUBIN(args...) TRACFBIN(args)
+#define TRACUBIN(args...)
+
+
+using namespace TRUSTEDBOOT;
+
+
+class TrustedBootTest: public CxxTest::TestSuite
+{
+ public:
+
+
+ /**
+ * @brief Helper to run failing marshal tests
+ */
+ void runTpmMarshalFailTest(TRUSTEDBOOT::TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t & o_cmdSize,
+ const char* i_testName,
+ int64_t & io_num_ops,
+ int64_t & io_fails)
+ {
+ errlHndl_t err = NULL;
+
+ err = tpmMarshalCommandData(i_cmd,
+ o_outbuf,
+ i_bufsize,
+ o_cmdSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalFailTest(%s) - Error not detected",
+ i_testName);
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ }
+ /**
+ * @brief Helper to run marshal tests
+ */
+ void runTpmMarshalTest(TRUSTEDBOOT::TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t & o_cmdSize,
+ const char* i_testName,
+ int64_t & io_num_ops,
+ int64_t & io_fails,
+ size_t i_expSize)
+ {
+ errlHndl_t err = NULL;
+ TRUSTEDBOOT::TPM2_BaseIn* baseCmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseIn*>(o_outbuf);
+
+ do
+ {
+
+
+ err = tpmMarshalCommandData(i_cmd,
+ o_outbuf,
+ i_bufsize,
+ o_cmdSize);
+ io_num_ops++;
+ if (NULL != err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalTest(%s) - Error detected", i_testName);
+ errlCommit( err,
+ TPMDD_COMP_ID );
+ delete err;
+ err = NULL;
+ break;
+ }
+ io_num_ops++;
+ if (o_cmdSize == 0 ||
+ o_cmdSize != baseCmd->commandSize ||
+ o_cmdSize != i_expSize)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalTest(%s) - Size Mismatch "
+ "oC %d aC %d Exp %d",
+ i_testName, o_cmdSize,
+ baseCmd->commandSize, i_expSize);
+ break;
+ }
+
+ // Try some that should fail
+ err = tpmMarshalCommandData(i_cmd,
+ o_outbuf,
+ i_expSize-1,
+ o_cmdSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalTest(%s) - Size-1 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ err = tpmMarshalCommandData(i_cmd,
+ o_outbuf,
+ i_expSize/2,
+ o_cmdSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalTest(%s) - Size/2 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ err = tpmMarshalCommandData(i_cmd,
+ o_outbuf,
+ i_expSize/3,
+ o_cmdSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmMarshalTest(%s) - Size/3 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ } while( 0 );
+ }
+
+
+ /**
+ * @brief Helper to run failing unmarshal tests
+ */
+ void runTpmUnmarshalFailTest(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TRUSTEDBOOT::TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize,
+ const char* i_testName,
+ int64_t & io_num_ops,
+ int64_t & io_fails)
+ {
+ errlHndl_t err = NULL;
+
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ i_respBufSize,
+ o_outBuf,
+ i_outBufSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalFailTest(%s) - Error not detected",
+ i_testName);
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ }
+ /**
+ * @brief Helper to run unmarshal tests
+ */
+ void runTpmUnmarshalTest(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TRUSTEDBOOT::TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize,
+ const char* i_testName,
+ int64_t & io_num_ops,
+ int64_t & io_fails)
+ {
+ errlHndl_t err = NULL;
+
+ do
+ {
+
+
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ i_respBufSize,
+ o_outBuf,
+ i_outBufSize);
+ io_num_ops++;
+ if (NULL != err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalTest(%s) - Error detected",
+ i_testName);
+ errlCommit( err,
+ TPMDD_COMP_ID );
+ delete err;
+ err = NULL;
+ break;
+ }
+
+ // Try some that should fail
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ 4,
+ o_outBuf,
+ i_outBufSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalTest(%s) - "
+ "RespBuf Size=4 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ // If the response output buffer is more then just the base we
+ // can do another failing size verif
+ if (i_outBufSize > sizeof(TPM2_BaseOut))
+ {
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ sizeof(TPM2_BaseOut),
+ o_outBuf,
+ i_outBufSize);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalTest(%s) - "
+ "RespBuf Size=10 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ }
+
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ i_respBufSize,
+ o_outBuf,
+ 4);
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalTest(%s) - "
+ "OutBuf Size=4 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+
+ if (i_outBufSize > sizeof(TPM2_BaseOut))
+ {
+ err = tpmUnmarshalResponseData(i_commandCode,
+ i_respBuf,
+ i_respBufSize,
+ o_outBuf,
+ sizeof(TPM2_BaseOut));
+ io_num_ops++;
+ if (NULL == err)
+ {
+ io_fails++;
+ TS_FAIL( "runTpmUnmarshalTest(%s) - "
+ "OutBuf Size=10 error not detected",
+ i_testName);
+ break;
+ }
+ else
+ {
+ delete err;
+ err = NULL;
+ }
+ }
+
+ } while( 0 );
+ }
+
+
+ /**
+ * @brief Test command marshaling
+ */
+ void testCommandMarshal ( void )
+ {
+ int64_t fails = 0, num_ops = 0;
+ uint8_t dataBufIn[BUFSIZE];
+ uint8_t dataBufOut[BUFSIZE];
+ size_t cmdSize = 0;
+ TRUSTEDBOOT::TPM2_BaseIn* baseCmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseIn*>(dataBufIn);
+
+ TRACFCOMP( g_trac_trustedboot,
+ "testCommandMarshal - Start" );
+ do
+ {
+
+ // Unsupported command
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+ baseCmd->commandCode = 0x12345;
+
+ runTpmMarshalFailTest(baseCmd,
+ dataBufOut,
+ sizeof(dataBufOut),
+ cmdSize,
+ "Unsupported command",
+ num_ops,
+ fails);
+ }
+
+ // Test 2ByteIn with Startup command
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+ TRUSTEDBOOT::TPM2_2ByteIn* cmdPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_2ByteIn*>(dataBufIn);
+ cmdPtr->base.commandCode = TRUSTEDBOOT::TPM_CC_Startup;
+
+ runTpmMarshalTest(baseCmd,
+ dataBufOut,
+ sizeof(dataBufOut),
+ cmdSize,
+ "2ByteIn",
+ num_ops,
+ fails,
+ sizeof(TPM2_2ByteIn));
+ }
+
+ // Test GetCapabilityIn
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+ TRUSTEDBOOT::TPM2_GetCapabilityIn* cmdPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityIn*>
+ (dataBufIn);
+ cmdPtr->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
+
+ runTpmMarshalTest(baseCmd,
+ dataBufOut,
+ sizeof(dataBufOut),
+ cmdSize,
+ "GetCapabilityIn",
+ num_ops,
+ fails,
+ sizeof(TPM2_GetCapabilityIn));
+ }
+
+
+
+ } while( 0 );
+ TRACFCOMP( g_trac_trustedboot,
+ "testCommandMarshal - End: %d/%d fails",
+ fails, num_ops );
+
+ }
+
+ /**
+ * @brief Test command unmarshaling
+ */
+ void testCommandUnmarshal ( void )
+ {
+ int64_t fails = 0, num_ops = 0;
+ uint8_t dataBufIn[BUFSIZE];
+ uint8_t dataBufOut[BUFSIZE];
+ TRUSTEDBOOT::TPM2_BaseOut* baseCmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseOut*>(dataBufOut);
+
+ TRACFCOMP( g_trac_trustedboot,
+ "testCommandUnmarshal - Start" );
+ do
+ {
+
+ // Unsupported command
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+
+ runTpmUnmarshalFailTest(0x12345,
+ dataBufIn,
+ sizeof(dataBufIn),
+ baseCmd,
+ sizeof(dataBufOut),
+ "Unsupported command",
+ num_ops,
+ fails);
+ }
+
+ // Test BaseOut with Startup command
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+
+ runTpmUnmarshalTest(TRUSTEDBOOT::TPM_CC_Startup,
+ dataBufIn,
+ sizeof(dataBufIn),
+ baseCmd,
+ sizeof(TPM2_BaseOut),
+ "BaseOut",
+ num_ops,
+ fails);
+ }
+
+ // Test GetCapabilityOut
+ {
+ memset(dataBufIn, 0, sizeof(dataBufIn));
+ memset(dataBufOut, 0, sizeof(dataBufOut));
+
+ // Test will fail because we haven't set the capability
+ runTpmUnmarshalFailTest(TRUSTEDBOOT::TPM_CC_GetCapability,
+ dataBufIn,
+ sizeof(dataBufIn),
+ baseCmd,
+ sizeof(TPM2_GetCapabilityOut),
+ "GetCapabilityOut - invalid cap",
+ num_ops,
+ fails);
+
+ // Set the capability coming from the TPM
+ TRUSTEDBOOT::TPM2_GetCapabilityOut* respPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityOut*>
+ (dataBufIn);
+ respPtr->capData.capability =
+ TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
+
+ runTpmUnmarshalTest(TRUSTEDBOOT::TPM_CC_GetCapability,
+ dataBufIn,
+ sizeof(dataBufIn),
+ baseCmd,
+ sizeof(TPM2_GetCapabilityOut),
+ "GetCapabilityOut",
+ num_ops,
+ fails);
+ }
+
+
+
+ } while( 0 );
+ TRACFCOMP( g_trac_trustedboot,
+ "testCommandUnmarshal - End: %d/%d fails",
+ fails, num_ops );
+
+ }
+
+
+};
+
+#endif
diff --git a/src/usr/secureboot/trusted/trustedTypes.C b/src/usr/secureboot/trusted/trustedTypes.C
new file mode 100644
index 000000000..404a56860
--- /dev/null
+++ b/src/usr/secureboot/trusted/trustedTypes.C
@@ -0,0 +1,219 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedTypes.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 trustedTypes.C
+ *
+ * @brief Trusted boot type inline functions
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <sys/time.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludstring.H>
+#include "trustedTypes.H"
+
+extern trace_desc_t* g_trac_trustedboot;
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+namespace TRUSTEDBOOT
+{
+
+ uint32_t getDigestSize(TPM_Alg_Id i_algId)
+ {
+ uint32_t ret = 0;
+ switch (i_algId)
+ {
+ case TPM_ALG_SHA1:
+ ret = TPM_ALG_SHA1_SIZE;
+ break;
+ case TPM_ALG_SHA256:
+ ret = TPM_ALG_SHA256_SIZE;
+ break;
+ default:
+ ret = 0;
+ break;
+ };
+ return ret;
+ }
+
+ uint8_t* unmarshalChunk(uint8_t* i_tpmBuf,
+ size_t & io_tpmBufSize,
+ void* o_chunkPtr,
+ size_t i_chunkSize)
+ {
+ if (NULL != i_tpmBuf)
+ {
+ if (i_chunkSize > io_tpmBufSize)
+ {
+ return NULL;
+ }
+ memcpy(o_chunkPtr, i_tpmBuf, i_chunkSize);
+ i_tpmBuf += i_chunkSize;
+ io_tpmBufSize -= i_chunkSize;
+ }
+ return i_tpmBuf;
+ }
+
+ uint8_t* marshalChunk(uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t & io_cmdSize,
+ void* i_chunkPtr,
+ size_t i_chunkSize)
+ {
+ if (NULL != o_tpmBuf)
+ {
+ if ((io_cmdSize + i_chunkSize) > i_tpmBufSize)
+ {
+ return NULL;
+ }
+ memcpy(o_tpmBuf, i_chunkPtr, i_chunkSize);
+ o_tpmBuf += i_chunkSize;
+ io_cmdSize += i_chunkSize;
+ }
+ return o_tpmBuf;
+ }
+
+ uint8_t* TPML_TAGGED_TPM_PROPERTY::unmarshal(uint8_t* i_tpmBuf,
+ size_t & io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &count, sizeof(count));
+
+ // Now we know the count as well
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &(tpmProperty[0]),
+ sizeof(TPMS_TAGGED_PROPERTY) * count);
+
+ return i_tpmBuf;
+ }
+
+ uint8_t* TPMS_CAPABILITY_DATA::unmarshal(uint8_t* i_tpmBuf,
+ size_t & io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &capability, sizeof(capability));
+
+ switch (capability)
+ {
+ case TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES:
+ {
+ return data.tpmProperties.unmarshal(i_tpmBuf, io_tpmBufSize,
+ i_outBufSize);
+ }
+ break;
+ default:
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPMS_CAPABILITY_DATA::unmarshal Unknown capability");
+ return NULL;
+ }
+ break;
+ }
+ return NULL;
+ }
+
+ size_t TPML_DIGEST_VALUES::marshalSize() const
+ {
+ size_t ret = sizeof(count);
+ for (size_t idx = 0; (idx < count && idx < HASH_COUNT); idx++)
+ {
+ ret += digests[idx].marshalSize();
+ }
+ return ret;
+ }
+
+ uint8_t* TPM2_BaseIn::marshal(uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t & io_cmdSize)
+ {
+ return marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ this, sizeof(TPM2_BaseIn));
+ }
+
+ uint8_t* TPM2_BaseOut::unmarshal(uint8_t* i_tpmBuf, size_t & io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ if (sizeof(TPM2_BaseOut) > i_outBufSize)
+ {
+ return NULL;
+ }
+ return unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ this, sizeof(TPM2_BaseOut));
+ }
+
+ uint8_t* TPM2_2ByteIn::marshal(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,
+ &param, sizeof(param));
+ }
+
+
+ uint8_t* TPM2_GetCapabilityIn::marshal(uint8_t* o_tpmBuf,
+ size_t i_tpmBufSize,
+ size_t& io_cmdSize)
+ {
+ // Base has already been marshaled
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &capability, sizeof(capability));
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &property, sizeof(property));
+ o_tpmBuf = marshalChunk(o_tpmBuf, i_tpmBufSize, io_cmdSize,
+ &propertyCount, sizeof(propertyCount));
+ return o_tpmBuf;
+ }
+
+ uint8_t* TPM2_GetCapabilityOut::unmarshal(uint8_t* i_tpmBuf,
+ size_t & io_tpmBufSize,
+ size_t i_outBufSize)
+ {
+ // Base has already been unmarshaled
+ if (sizeof(TPM2_GetCapabilityOut) > i_outBufSize)
+ {
+ return NULL;
+ }
+ i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize,
+ &moreData, sizeof(moreData));
+
+ // Capability data block
+ return capData.unmarshal(i_tpmBuf, io_tpmBufSize, i_outBufSize);
+
+ }
+
+
+} // end TRUSTEDBOOT
diff --git a/src/usr/secureboot/trusted/trustedTypes.H b/src/usr/secureboot/trusted/trustedTypes.H
new file mode 100644
index 000000000..c32128a60
--- /dev/null
+++ b/src/usr/secureboot/trusted/trustedTypes.H
@@ -0,0 +1,297 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedTypes.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 trustedTypes.H
+ *
+ * @brief Trustedboot TPM Types
+ *
+ */
+#ifndef __TRUSTEDTYPES_H
+#define __TRUSTEDTYPES_H
+// -----------------------------------------------
+// Includes
+// -----------------------------------------------
+#include <secureboot/trustedbootif.H>
+
+namespace TRUSTEDBOOT
+{
+
+
+
+ /// TPM Algorithm defines
+ enum TPM_Alg_Id
+ {
+ TPM_ALG_SHA1 = 0x0004,
+ TPM_ALG_SHA256 = 0x000B,
+ };
+
+ /// Common static values
+ enum
+ {
+ MAX_SYSTEM_TPMS = 2,
+ TPM_MASTER_INDEX = 0, ///< Index into tpm array for master chip
+ TPM_BACKUP_INDEX = 1, ///< Index for backup TPM
+ MAX_TPM_LOG_MSG = 128, ///< Maximum log message size
+
+ HASH_COUNT = 1, ///< Maximum # of digests
+ TPM_ALG_SHA1_SIZE = 20, ///< SHA1 digest byte size
+ TPM_ALG_SHA256_SIZE = 32, ///< SHA256 digest byte size
+
+ // Event types
+ EV_NO_ACTION = 0x3, ///< Event field contains info
+ EV_ACTION = 0x5, ///< Must extend a PCR
+
+ };
+
+ /// Class object to store system TPM information
+ class SystemTpms
+ {
+ public:
+ SystemTpms();
+
+ TpmTarget tpm[MAX_SYSTEM_TPMS];
+ };
+
+ /**
+ * @brief Get the digest size of the selected hash algorithm
+ * @param[in] i_algId Algorith ID to query
+ * @returns digest length in bytes, 0 on invalid algorithm
+ */
+ uint32_t getDigestSize(TPM_Alg_Id i_algId);
+
+
+ /// Various static values
+ enum
+ {
+ // TPM Spec supported
+ TPM_SPEC_MAJOR = 2,
+ TPM_SPEC_MINOR = 0,
+ TPM_SPEC_ERRATA = 0,
+ TPM_PLATFORM_SERVER = 1,
+
+ // Command structure tags
+ TPM_ST_NO_SESSIONS = 0x8001, ///< A command with no sess/auth
+ TPM_ST_SESSIONS = 0x8002, ///< A command has sessions
+
+ // Command Codes
+ TPM_CC_Startup = 0x00000144,
+ TPM_CC_GetCapability = 0x0000017A,
+ TPM_CC_PCR_Read = 0x0000017E,
+ TPM_CC_PCR_Extend = 0x00000182,
+
+
+ // TPM Startup types
+ TPM_SU_CLEAR = 0x0000,///< TPM perform reset,restart
+ TPM_SU_STATE = 0x0001,///< TPM perform restore saved state
+
+ // Capability
+ MAX_TPM_PROPERTIES = 2,
+ TPM_CAP_TPM_PROPERTIES = 0x00000006, ///< Pull TPM Properties
+
+ // TPM Properties
+ TPM_PT_MANUFACTURER = 0x00000105,
+ TPM_PT_FIRMWARE_VERSION_1 = 0x0000010B,
+ TPM_PT_FIRMWARE_VERSION_2 = 0x0000010C,
+
+
+ // TPM Return Codes
+ TPM_SUCCESS = 0x000,
+
+ TPM_RC_INITIALIZE = 0x100,
+
+ };
+
+
+ // Command structures taken from Trusted Platform Module Library Part 3:
+ // Commands Family "2.0"
+
+ /// TPM capability response structure
+ struct TPMS_TAGGED_PROPERTY
+ {
+ uint32_t property; ///< TPM_PT_xx identifier
+ uint32_t value; ///< value of the property
+ } PACKED;
+
+ struct TPML_TAGGED_TPM_PROPERTY
+ {
+ uint32_t count; ///< Number of properties
+ TPMS_TAGGED_PROPERTY tpmProperty[MAX_TPM_PROPERTIES];
+ uint8_t* unmarshal(uint8_t* i_tpmBuf, size_t & io_tpmBufSize,
+ size_t i_outBufSize);
+ } PACKED;
+
+ union TPMU_CAPABILITIES
+ {
+ // Currently only TPM properties supported
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ } PACKED;
+
+ struct TPMS_CAPABILITY_DATA
+ {
+ uint32_t capability; ///< The capability type
+ TPMU_CAPABILITIES data; ///< The capability data
+ uint8_t* unmarshal(uint8_t* i_tpmBuf, size_t & io_tpmBufSize,
+ size_t i_outBufSize);
+ } PACKED;
+
+
+ /// SHA1 Event log entry format
+ struct TCG_PCR_EVENT
+ {
+ uint32_t pcrIndex; ///< PCRIndex event extended to
+ uint32_t eventType; ///< Type of event
+ uint8_t digest[20]; ///< Value extended into PCR index
+ uint32_t eventSize; ///< Size of event data
+ uint8_t event[0]; ///< The event data
+
+ inline size_t marshalSize() const
+ { return (sizeof(TCG_PCR_EVENT) + eventSize); }
+
+ } PACKED;
+
+ /// Digest union
+ union TPMU_HA
+ {
+ uint8_t sha1[TPM_ALG_SHA1_SIZE];
+ uint8_t sha256[TPM_ALG_SHA256_SIZE];
+ } PACKED;
+
+ /// Crypto agile digest
+ struct TPMT_HA
+ {
+ uint16_t algorithmId; ///< ID of hashing algorithm
+ TPMU_HA digest; ///< Digest, depends on algorithmid
+ inline size_t marshalSize() const;
+ } PACKED;
+
+ inline size_t TPMT_HA::marshalSize() const
+ {
+ return (sizeof(TPMT_HA) - sizeof(TPMU_HA) +
+ getDigestSize((TPM_Alg_Id)algorithmId));
+ }
+
+ /// Crypto agile digests list
+ struct TPML_DIGEST_VALUES
+ {
+ uint32_t count; ///< Number of digests
+ TPMT_HA digests[HASH_COUNT]; ///< Digests
+ size_t marshalSize() const;
+ } PACKED;
+
+ /// Event field structure
+ struct TPM_EVENT_FIELD
+ {
+ uint32_t eventSize; ///< Size of event data
+ uint8_t event[MAX_TPM_LOG_MSG]; ///< The event data
+ /**
+ * @brief Return size of entire structure
+ */
+ inline size_t marshalSize() const;
+ } PACKED;
+ inline size_t TPM_EVENT_FIELD::marshalSize() const
+ {
+ return (sizeof(eventSize) + eventSize);
+ }
+
+ /// Crypto agile log entry format
+ struct TCG_PCR_EVENT2
+ {
+ uint32_t pcrIndex; ///< PCRIndex event extended to
+ uint32_t eventType; ///< Type of event
+ TPML_DIGEST_VALUES digests; ///< List of digests extended to PCRIndex
+ TPM_EVENT_FIELD event; ///< Event information
+
+ } PACKED;
+
+
+ struct TPM2_BaseIn
+ {
+ uint16_t tag; ///< Type TPM_ST_xx
+ uint32_t commandSize; ///< Total # output bytes incl cmdSize & tag
+ uint32_t commandCode; ///< Type TPM_CC_xx
+ uint8_t* marshal(uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t & io_cmdSize);
+ } PACKED;
+
+ /// Base of all outgoing messages
+ struct TPM2_BaseOut
+ {
+ uint16_t tag; ///< Type TPM_ST_xx
+ uint32_t responseSize; ///< Total # out bytes incl paramSize & tag
+ uint32_t responseCode; ///< The return code of the operation
+ uint8_t* unmarshal(uint8_t* i_tpmBuf, size_t & io_tpmBufSize,
+ size_t i_outBufSize);
+ } PACKED;
+
+ /// Generic TPM Input Command structure with a 2 byte param
+ struct TPM2_2ByteIn
+ {
+ TPM2_BaseIn base;
+ uint16_t param;
+ uint8_t* marshal(uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t & io_cmdSize);
+ } PACKED;
+
+
+ /// Generic TPM Output Command structure with a 4 byte return data
+ struct TPM2_4ByteOut
+ {
+ TPM2_BaseOut base;
+ uint32_t resp;
+ } PACKED;
+
+ /// Incoming TPM_GetCapability structure
+ struct TPM2_GetCapabilityIn
+ {
+ TPM2_BaseIn base;
+ uint32_t capability; ///< group selection
+ uint32_t property; ///< Further definition
+ uint32_t propertyCount; ///< Number of properties to return
+ uint8_t* marshal(uint8_t* o_tpmBuf, size_t i_tpmBufSize,
+ size_t& io_cmdSize);
+ } PACKED;
+
+ /// Outgoing TPM_GetCapability structure
+ struct TPM2_GetCapabilityOut
+ {
+ TPM2_BaseOut base;
+ uint8_t moreData; ///< Flag to indicate if more values available
+ TPMS_CAPABILITY_DATA capData; ///< The capability response
+ uint8_t* unmarshal(uint8_t* i_tpmBuf, size_t & io_tpmBufSize,
+ size_t i_outBufSize);
+ } PACKED;
+
+
+ /// Incoming TPM_EXTEND structure
+ struct TPM2_ExtendIn
+ {
+ TPM2_BaseIn base;
+ uint32_t pcrHandle; ///< PCR number to extend
+ TPML_DIGEST_VALUES digests; ///< Values to be extended
+ } PACKED;
+
+} // end TRUSTEDBOOT namespace
+#endif
+
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index 631448ad7..cf777d0f5 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -39,11 +39,9 @@
#include <errl/errludtarget.H>
#include <errl/errludstring.H>
#include <targeting/common/targetservice.H>
-#include <devicefw/driverif.H>
-#include <i2c/tpmddif.H>
#include <secureboot/trustedbootif.H>
-#include <i2c/tpmddreasoncodes.H>
#include "trustedboot.H"
+#include "trustedTypes.H"
#include <secureboot/trustedboot_reasoncodes.H>
// ----------------------------------------------
@@ -100,8 +98,13 @@ void* host_update_master_tpm( void *io_pArgs )
TPMDD::TPM_PRIMARY);
}
+ else
+ {
+ systemTpms.tpm[TPM_MASTER_INDEX].available = false;
+ }
- if (systemTpms.tpm[TPM_MASTER_INDEX].failed)
+ if (systemTpms.tpm[TPM_MASTER_INDEX].failed ||
+ !systemTpms.tpm[TPM_MASTER_INDEX].available)
{
/// @todo RTC:134913 Switch to backup chip if backup TPM avail
@@ -131,6 +134,24 @@ void* host_update_master_tpm( void *io_pArgs )
}
+ // Lastly we will check on the backup TPM and see if it is enabled
+ // in the attributes at least
+ TPMDD::tpm_info_t tpmInfo;
+ tpmInfo.chip = TPMDD::TPM_BACKUP;
+ err = TPMDD::tpmReadAttributes(nodeTarget, tpmInfo);
+ if (NULL != err)
+ {
+ break;
+ }
+ else if (!tpmInfo.tpmEnabled)
+ {
+ TRACUCOMP( g_trac_trustedboot,
+ "host_update_master_tpm() tgt=0x%X "
+ "Marking backup TPM unavailable",
+ TARGETING::get_huid(nodeTarget));
+ systemTpms.tpm[TPM_BACKUP_INDEX].available = false;
+ }
+
} while ( 0 );
if( unlock )
@@ -151,9 +172,6 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
TPMDD::tpm_chip_types_t i_chip)
{
errlHndl_t err = NULL;
- uint8_t dataBuf[BUFSIZE];
- size_t dataSize = sizeof(dataBuf);
- size_t cmdSize = 0;
TRACDCOMP( g_trac_trustedboot,
ENTER_MRK"tpmInitialize()" );
@@ -164,86 +182,60 @@ void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
do
{
+
// TPM Initialization sequence
io_target.nodeTarget = i_nodeTarget;
io_target.chip = i_chip;
io_target.initAttempted = true;
+ io_target.available = true;
io_target.failed = false;
- // Send the TPM startup command
- // Build our command block for a startup
- memset(dataBuf, 0, sizeof(dataBuf));
-
- TRUSTEDBOOT::TPM2_BaseOut* resp =
- (TRUSTEDBOOT::TPM2_BaseOut*)dataBuf;
- TRUSTEDBOOT::TPM2_2ByteIn* cmd =
- (TRUSTEDBOOT::TPM2_2ByteIn*)dataBuf;
-
- cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
- cmd->base.commandSize = sizeof (TRUSTEDBOOT::TPM2_2ByteIn);
- cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_Startup;
- cmd->param = TRUSTEDBOOT::TPM_SU_CLEAR;
- cmdSize = cmd->base.commandSize;
-
- err = deviceRead(io_target.nodeTarget,
- &dataBuf,
- dataSize,
- DEVICE_TPM_ADDRESS( io_target.chip,
- TPMDD::TPM_OP_TRANSMIT,
- cmdSize) );
-
+ // TPM_STARTUP
+ err = tpmCmdStartup(io_target);
if (NULL != err)
{
- TRACFCOMP( g_trac_trustedboot,
- "TPM STARTUP I2C Fail %X : ",
- err->reasonCode() );
break;
-
}
- else if (TRUSTEDBOOT::TPM_SUCCESS != resp->responseCode)
- {
- TRACFCOMP( g_trac_trustedboot,
- "TPM STARTUP OP Fail %X : ",
- resp->responseCode);
-
- /*@
- * @errortype
- * @reasoncode RC_TPM_START_FAIL
- * @severity ERRL_SEV_UNRECOVERABLE
- * @moduleid MOD_TPM_INITIALIZE
- * @userdata1 node
- * @userdata2 returnCode
- * @devdesc Invalid operation type.
- */
- err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MOD_TPM_INITIALIZE,
- RC_TPM_START_FAIL,
- TARGETING::get_huid(
- io_target.nodeTarget),
- resp->responseCode,
- true /*Add HB SW Callout*/ );
- err->collectTrace( SECURE_COMP_NAME );
+ // TPM_GETCAPABILITY to read FW Version
+ err = tpmCmdGetCapFwVersion(io_target);
+ if (NULL != err)
+ {
break;
}
+
} while ( 0 );
// If the TPM failed we will mark it not functional
if (NULL != err)
{
- io_target.failed = true;
+ tpmMarkFailed(io_target);
// Log this failure
errlCommit(err, SECURE_COMP_ID);
}
TRACDCOMP( g_trac_trustedboot,
- EXIT_MRK"tpmInitialize() - %s",
- ((NULL == err) ? "No Error" : "With Error") );
+ EXIT_MRK"tpmInitialize()");
+
+}
+
+void tpmMarkFailed(TRUSTEDBOOT::TpmTarget & io_target)
+{
+
+ TRACFCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmMarkFailed() Marking TPM as failed : "
+ "tgt=0x%X chip=%d",
+ TARGETING::get_huid(io_target.nodeTarget),
+ io_target.chip);
+
+ io_target.failed = true;
+ /// @todo RTC:125287 Add fail marker to TPM log and disable TPM access
}
+
} // end TRUSTEDBOOT
diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H
index 3e3b43411..76630ba9a 100644
--- a/src/usr/secureboot/trusted/trustedboot.H
+++ b/src/usr/secureboot/trusted/trustedboot.H
@@ -34,110 +34,91 @@
// Includes
// -----------------------------------------------
#include <secureboot/trustedbootif.H>
+#include <i2c/tpmddif.H>
+#include "trustedTypes.H"
namespace TRUSTEDBOOT
{
enum
{
- MAX_SYSTEM_TPMS = 2,
BUFSIZE = 256,
- TPM_MASTER_INDEX = 0, ///< Index into tpmTargets array for master chip
- TPM_BACKUP_INDEX = 1, ///< Index for backup chip TPM
+ MAX_TRANSMIT_SIZE = 1024, ///< Maximum send/receive transmit size
};
-
/**
* @brief Initialize the targetted TPM
* @param[in/out] io_target Current TPM target structure
* @param[in] i_nodeTarget Node Target
* @param[in] i_chip Chip to initialize
*/
- void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
- TARGETING::Target* i_nodeTarget,
- TPMDD::tpm_chip_types_t i_chip);
-
-/// Class object to store system TPM information
-class SystemTpms
-{
-public:
- SystemTpms();
-
- TpmTarget tpm[MAX_SYSTEM_TPMS];
-};
-
-// Command structures taken from Trusted Platform Module Library Part 3:
-// Commands Family "2.0"
-struct TPM2_BaseIn {
- uint16_t tag; ///< Type TPM_ST_xx
- uint32_t commandSize; ///< Total # output bytes incl cmdSize and tag
- uint32_t commandCode; ///< Type TPM_CC_xx
-} PACKED;
-
-/// Base of all outgoing messages
-struct TPM2_BaseOut {
- uint16_t tag; ///< Type TPM_ST_xx
- uint32_t responseSize; ///< Total # output bytes incl paramSize and tag
- uint32_t responseCode;///< The return code of the operation
-} PACKED;
-
-/// Generic TPM Input Command structure with a 2 byte param
-struct TPM2_2ByteIn {
- TPM2_BaseIn base;
- uint16_t param;
-} PACKED;
-
-/// Generic TPM Output Command structure with a 4 byte return data
-struct TPM2_4ByteOut {
- TPM2_BaseOut base;
- uint32_t resp;
-} PACKED;
+void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target,
+ TARGETING::Target* i_nodeTarget,
+ TPMDD::tpm_chip_types_t i_chip);
-/// Incoming TPM_GetCapability structure
-struct TPM2_GetCapabilityIn {
- TPM2_BaseIn base;
- uint32_t capability; ///< group selection
- uint32_t property; ///< Further definition
- uint32_t propertyCount; ///< Number of properties to return
-} PACKED;
-
-/// Outgoing TPM_GetCapability structure
-struct TPM2_GetCapabilityOut {
- TPM2_BaseOut base;
- uint8_t moreData; ///< Flag to indicate if more values available
- uint8_t capData[]; ///< The capability response
-} PACKED;
-
-/// Various static values
-enum {
- // Command structure tags
- TPM_ST_NO_SESSIONS = 0x8001, ///< A command with no sess/auth
-
-
- // Command Codes
- TPM_CC_Startup = 0x00000144,
- TPM_CC_GetCapability = 0x0000017A,
- TPM_CC_PCR_Read = 0x0000017E,
- TPM_CC_PCR_Extend = 0x00000182,
-
-
- // TPM Startup types
- TPM_SU_CLEAR = 0x0000, ///< TPM perform reset,restart
- TPM_SU_STATE = 0x0001, ///< TPM perform restore saved state
-
- // Capability
- TPM_CAP_TPM_PROPERTIES = 0x00000006, ///< Pull TPM Properties
+/**
+ * @brief Mark the TPM as non-functional and take required steps
+ * @param[in/out] io_target Current TPM target structure
+ */
+void tpmMarkFailed(TRUSTEDBOOT::TpmTarget & io_target);
- // TPM Properties
- TPM_PT_MANUFACTURER = 0x00000105,
+/**
+ * @brief Transmit the command to the TPM and perform marshaling
+ * @param[in/out] io_target Current TPM target structure
+ * @param[in/out] io_buffer Input the command buffer to send, response on exit
+ * @param[in] i_bufsize Size of io_buffer in bytes
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmTransmitCommand(TRUSTEDBOOT::TpmTarget & io_target,
+ uint8_t* io_buffer,
+ size_t i_bufsize );
- // TPM Return Codes
- TPM_SUCCESS = 0x000,
+/**
+ * @brief Take structure pointed to by cmd and format for input into TPM
+ * @param[in] i_cmd Prefilled command input structure
+ * @param[out] o_outbuf Buffer to place marshalled data
+ * @param[in] i_bufsize Size of o_outbuf in bytes
+ * @param[out] o_cmdSize Byte size of io_outbuf data after marshal
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmMarshalCommandData(TRUSTEDBOOT::TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t & o_cmdSize);
- TPM_RC_INITIALIZE = 0x100,
+/**
+ * @brief Take structure pointed to by cmd and format for input into TPM
+ * @param[in] i_commandCode Command code that was executed on the TPM
+ * @param[in] i_respBuf Buffer with response data from TPM
+ * @param[in] i_respBufSize Byte size of respBuf buffer from TPM
+ * @param[out] o_outBuf Buffer to place formatted response data
+ * @param[in] i_outBufSize Byte size of o_outBuf buffer
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TRUSTEDBOOT::TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize);
+/**
+ * @brief Send the TPM_STARTUP command to the targetted TPM
+ * @param[in/out] io_target Current TPM target structure
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t tpmCmdStartup(TRUSTEDBOOT::TpmTarget & io_target);
-};
+/**
+ * @brief Send the TPM_GETCAPABILITY command to read FW version from TPM
+ * @param[in/out] io_target Current TPM target structure
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+*/
+errlHndl_t tpmCmdGetCapFwVersion(TRUSTEDBOOT::TpmTarget & io_target);
} // end TRUSTEDBOOT namespace
diff --git a/src/usr/secureboot/trusted/trustedbootCmds.C b/src/usr/secureboot/trusted/trustedbootCmds.C
new file mode 100644
index 000000000..311d1fce8
--- /dev/null
+++ b/src/usr/secureboot/trusted/trustedbootCmds.C
@@ -0,0 +1,717 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/trusted/trustedbootCmds.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 trustedbootCmds.C
+ *
+ * @brief Trusted boot TPM command interfaces
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <sys/time.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludstring.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/driverif.H>
+#include <i2c/tpmddif.H>
+#include <secureboot/trustedbootif.H>
+#include <i2c/tpmddreasoncodes.H>
+#include "trustedboot.H"
+#include "trustedTypes.H"
+#include <secureboot/trustedboot_reasoncodes.H>
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_trustedboot;
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+//#define TRACUBIN(args...) TRACFBIN(args)
+#define TRACUBIN(args...)
+
+namespace TRUSTEDBOOT
+{
+
+
+errlHndl_t tpmTransmitCommand(TRUSTEDBOOT::TpmTarget & io_target,
+ uint8_t* io_buffer,
+ size_t i_bufsize )
+{
+ errlHndl_t err = NULL;
+ uint8_t* transmitBuf = NULL;
+ size_t cmdSize = 0;
+ size_t dataSize = 0;
+ TRUSTEDBOOT::TPM2_BaseIn* cmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseIn*>(io_buffer);
+ TRUSTEDBOOT::TPM2_BaseOut* resp =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseOut*>(io_buffer);
+
+ TRACUCOMP( g_trac_trustedboot,
+ ENTER_MRK"TPM TRANSMIT CMD START : BufLen %d : %016llx",
+ i_bufsize,
+ *(reinterpret_cast<uint64_t*>(io_buffer)) );
+
+ do
+ {
+ transmitBuf = new uint8_t[MAX_TRANSMIT_SIZE];
+
+ // Marshal the data into a byte array for transfer to the TPM
+ err = tpmMarshalCommandData(cmd,
+ transmitBuf,
+ MAX_TRANSMIT_SIZE,
+ cmdSize);
+ if (NULL != err)
+ {
+ break;
+ }
+
+
+ // Send to the TPM
+ dataSize = MAX_TRANSMIT_SIZE;
+ err = deviceRead(io_target.nodeTarget,
+ transmitBuf,
+ dataSize,
+ DEVICE_TPM_ADDRESS( io_target.chip,
+ TPMDD::TPM_OP_TRANSMIT,
+ cmdSize));
+ if (NULL != err)
+ {
+ break;
+ }
+
+ // Unmarshal the response
+ err = tpmUnmarshalResponseData(cmd->commandCode,
+ transmitBuf,
+ dataSize,
+ resp,
+ i_bufsize);
+
+
+ } while ( 0 );
+
+
+ delete transmitBuf;
+
+ TRACUCOMP( g_trac_trustedboot,
+ EXIT_MRK"tpmTransmitCommand() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+errlHndl_t tpmMarshalCommandData(TRUSTEDBOOT::TPM2_BaseIn* i_cmd,
+ uint8_t* o_outbuf,
+ size_t i_bufsize,
+ size_t & o_cmdSize)
+{
+ errlHndl_t err = NULL;
+ uint8_t* sBuf = o_outbuf;
+ o_cmdSize = 0;
+ int stage = 0;
+ TRUSTEDBOOT::TPM2_BaseIn* baseCmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseIn*>(o_outbuf);
+
+ TRACDCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmMarshalCommandData()" );
+ do
+ {
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM MARSHAL START : BufLen %d : %016llx",
+ i_bufsize,
+ *(reinterpret_cast<uint64_t*>(i_cmd)) );
+
+ // Start with the command header
+ sBuf = i_cmd->marshal(sBuf, i_bufsize, o_cmdSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+
+
+ // Marshal the handles
+ stage = 1;
+
+
+ // Marshal the authorizations
+ stage = 2;
+
+ // Marshal the parameters
+ stage = 3;
+ switch (i_cmd->commandCode)
+ {
+ // Two byte parm fields
+ case TRUSTEDBOOT::TPM_CC_Startup:
+ {
+ TRUSTEDBOOT::TPM2_2ByteIn* cmdPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_2ByteIn*>(i_cmd);
+ sBuf = cmdPtr->marshal(sBuf,
+ i_bufsize,
+ o_cmdSize);
+ }
+ break;
+
+ case TRUSTEDBOOT::TPM_CC_GetCapability:
+ {
+ TRUSTEDBOOT::TPM2_GetCapabilityIn* cmdPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityIn*>(i_cmd);
+ sBuf = cmdPtr->marshal(sBuf,
+ i_bufsize,
+ o_cmdSize);
+ }
+ break;
+
+ default:
+ {
+ // Command code not supported
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL INVALID COMMAND : %X",
+ i_cmd->commandCode );
+ sBuf = NULL;
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_MARSHAL_INVALID_CMD
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_MARSHALCMDDATA
+ * @userdata1 Command Code
+ * @userdata2 0
+ * @devdesc Unsupported command code during marshal
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_MARSHALCMDDATA,
+ RC_TPM_MARSHAL_INVALID_CMD,
+ i_cmd->commandCode,
+ 0,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ }
+ break;
+ };
+
+ if (NULL != err)
+ {
+ break;
+ }
+
+
+ // Lastly now that we know the size update the byte stream
+ baseCmd->commandSize = o_cmdSize;
+
+ } while ( 0 );
+
+ if (NULL == sBuf && NULL == err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM MARSHAL FAILURE : Stage %d", stage);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_MARSHALING_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_MARSHALCMDDATA
+ * @userdata1 stage
+ * @userdata2 0
+ * @devdesc Marshaling error detected
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_MARSHALCMDDATA,
+ RC_TPM_MARSHALING_FAIL,
+ stage,
+ 0,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+
+ }
+
+ TRACUBIN(g_trac_trustedboot, "Marshal Out",
+ o_outbuf, o_cmdSize);
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM MARSHAL END : CmdSize: %d : %016llx ", o_cmdSize,
+ *(reinterpret_cast<uint64_t*>(o_outbuf)) );
+
+ TRACDCOMP( g_trac_trustedboot,
+ EXIT_MRK"tpmMarshalCommandData()" );
+
+ return err;
+}
+
+errlHndl_t tpmUnmarshalResponseData(uint32_t i_commandCode,
+ uint8_t* i_respBuf,
+ size_t i_respBufSize,
+ TRUSTEDBOOT::TPM2_BaseOut* o_outBuf,
+ size_t i_outBufSize)
+{
+ errlHndl_t err = NULL;
+ uint8_t* sBuf = i_respBuf;
+ int stage = 0;
+
+ TRACDCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmUnmarshalResponseData()" );
+
+ do {
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL START : RespBufLen %d : OutBufLen %d",
+ i_respBufSize, i_outBufSize);
+ TRACUBIN(g_trac_trustedboot,"Unmarshal In",
+ i_respBuf, i_respBufSize);
+
+
+ // Start with the response header
+ stage = 1;
+ sBuf = o_outBuf->unmarshal(sBuf, i_respBufSize, i_outBufSize);
+ if (NULL == sBuf)
+ {
+ break;
+ }
+
+ // If the TPM returned a failure it will not send the rest
+ // Let the caller deal with the RC
+ if (TRUSTEDBOOT::TPM_SUCCESS != o_outBuf->responseCode)
+ {
+ break;
+ }
+
+
+ // Unmarshal the parameters
+ stage = 2;
+ switch (i_commandCode)
+ {
+ // Empty response commands
+ case TRUSTEDBOOT::TPM_CC_Startup:
+ // Nothing to do
+ break;
+
+ case TRUSTEDBOOT::TPM_CC_GetCapability:
+ {
+ TRUSTEDBOOT::TPM2_GetCapabilityOut* respPtr =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityOut*>
+ (o_outBuf);
+ sBuf = respPtr->unmarshal(sBuf, i_respBufSize, i_outBufSize);
+
+ }
+ break;
+
+ default:
+ {
+ // Command code not supported
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL INVALID COMMAND : %X",
+ i_commandCode );
+ sBuf = NULL;
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_UNMARSHAL_INVALID_CMD
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_UNMARSHALRESPDATA
+ * @userdata1 commandcode
+ * @userdata2 stage
+ * @devdesc Unsupported command code during unmarshal
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_UNMARSHALRESPDATA,
+ RC_TPM_UNMARSHAL_INVALID_CMD,
+ i_commandCode,
+ stage,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ }
+ break;
+ }
+
+
+ } while ( 0 );
+
+ if (NULL == sBuf && NULL == err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL FAILURE : Stage %d", stage);
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_UNMARSHALING_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_UNMARSHALRESPDATA
+ * @userdata1 Stage
+ * @userdata2 Remaining response buffer size
+ * @devdesc Unmarshaling error detected
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_UNMARSHALRESPDATA,
+ RC_TPM_UNMARSHALING_FAIL,
+ stage,
+ i_respBufSize,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+
+
+ }
+
+ TRACUCOMP( g_trac_trustedboot,
+ "TPM UNMARSHAL END : %016llx ",
+ *(reinterpret_cast<uint64_t*>(o_outBuf)) );
+
+ TRACDCOMP( g_trac_trustedboot,
+ EXIT_MRK"tpmUnmarshalResponseData()" );
+
+ return err;
+}
+
+errlHndl_t tpmCmdStartup(TRUSTEDBOOT::TpmTarget & io_target)
+{
+ errlHndl_t err = NULL;
+ uint8_t dataBuf[BUFSIZE];
+
+ TRACDCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmCmdStartup()" );
+ TRACUCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmCmdStartup() tgt=0x%X chip=%d",
+ TARGETING::get_huid(io_target.nodeTarget),
+ io_target.chip);
+
+ do
+ {
+ // Send the TPM startup command
+ // Build our command block for a startup
+ memset(dataBuf, 0, sizeof(dataBuf));
+
+ TRUSTEDBOOT::TPM2_BaseOut* resp =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_BaseOut*>(dataBuf);
+
+ TRUSTEDBOOT::TPM2_2ByteIn* cmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_2ByteIn*>(dataBuf);
+
+ cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_Startup;
+ cmd->param = TRUSTEDBOOT::TPM_SU_CLEAR;
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (NULL != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM STARTUP transmit Fail %X : ",
+ err->reasonCode() );
+ break;
+
+ }
+ else if (TRUSTEDBOOT::TPM_SUCCESS != resp->responseCode)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM STARTUP OP Fail %X : ",
+ resp->responseCode);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_START_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_STARTUP
+ * @userdata1 node
+ * @userdata2 responseCode
+ * @devdesc Invalid operation type.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_CMD_STARTUP,
+ RC_TPM_START_FAIL,
+ TARGETING::get_huid(
+ io_target.nodeTarget),
+ resp->responseCode,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+
+
+ } while ( 0 );
+
+
+ TRACUCOMP( g_trac_trustedboot,
+ EXIT_MRK"tpmCmdStartup() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+errlHndl_t tpmCmdGetCapFwVersion(TRUSTEDBOOT::TpmTarget & io_target)
+{
+ errlHndl_t err = NULL;
+ uint8_t dataBuf[BUFSIZE];
+ size_t dataSize = BUFSIZE;
+ uint16_t fwVersion[4] = {0xFF, 0xFF, 0xFF, 0xFF};
+
+ TRACDCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmCmdGetCapFwVersion()" );
+ TRACUCOMP( g_trac_trustedboot,
+ ENTER_MRK"tpmCmdGetCapFwVersion() tgt=0x%X chip=%d",
+ TARGETING::get_huid(io_target.nodeTarget),
+ io_target.chip);
+
+ do
+ {
+
+ // Build our command block for a get capability of the FW version
+ memset(dataBuf, 0, dataSize);
+
+ TRUSTEDBOOT::TPM2_GetCapabilityOut* resp =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityOut*>(dataBuf);
+ TRUSTEDBOOT::TPM2_GetCapabilityIn* cmd =
+ reinterpret_cast<TRUSTEDBOOT::TPM2_GetCapabilityIn*>(dataBuf);
+
+ cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
+ cmd->capability = TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
+ cmd->property = TRUSTEDBOOT::TPM_PT_FIRMWARE_VERSION_1;
+ cmd->propertyCount = 1;
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (NULL != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP Transmit Fail %X : ",
+ err->reasonCode() );
+ break;
+
+ }
+
+ if (TRUSTEDBOOT::TPM_SUCCESS != resp->base.responseCode)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP OP Fail %X Size(%d) ",
+ resp->base.responseCode,
+ dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 node
+ * @userdata2[0:31] responseCode
+ * @userdata2[32:63] dataSize
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP_FAIL,
+ TARGETING::get_huid(
+ io_target.nodeTarget),
+ resp->base.responseCode,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+ else
+ {
+ // Walk the reponse data to pull the high order bytes out
+
+ if (resp->capData.capability != TPM_CAP_TPM_PROPERTIES ||
+ resp->capData.data.tpmProperties.count != 1 ||
+ resp->capData.data.tpmProperties.tpmProperty[0].property !=
+ TPM_PT_FIRMWARE_VERSION_1) {
+
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP FW INVALID DATA "
+ "Cap(%X) Cnt(%X) Prop(%X)",
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.count,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP_FW_INVALID_RESP
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 node
+ * @userdata2[0:31] capability
+ * @userdata2[32:63] propery
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP_FW_INVALID_RESP,
+ TARGETING::get_huid(
+ io_target.nodeTarget),
+ ((uint64_t)resp->capData.capability << 32) |
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+ else
+ {
+ fwVersion[0] =
+ (resp->capData.data.
+ tpmProperties.tpmProperty[0].value >> 16);
+ fwVersion[1] =
+ (resp->capData.data.
+ tpmProperties.tpmProperty[0].value & 0xFFFF);
+ }
+
+ }
+
+ // Read part 2 of the version
+ dataSize = BUFSIZE;
+ memset(dataBuf, 0, dataSize);
+
+ cmd->base.tag = TRUSTEDBOOT::TPM_ST_NO_SESSIONS;
+ cmd->base.commandCode = TRUSTEDBOOT::TPM_CC_GetCapability;
+ cmd->capability = TRUSTEDBOOT::TPM_CAP_TPM_PROPERTIES;
+ cmd->property = TRUSTEDBOOT::TPM_PT_FIRMWARE_VERSION_2;
+ cmd->propertyCount = 1;
+
+
+ err = tpmTransmitCommand(io_target,
+ dataBuf,
+ sizeof(dataBuf));
+
+ if (NULL != err)
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 Transmit Fail %X : ",
+ err->reasonCode() );
+ break;
+
+ }
+
+ if ((sizeof(TRUSTEDBOOT::TPM2_GetCapabilityOut) > dataSize) ||
+ (TRUSTEDBOOT::TPM_SUCCESS != resp->base.responseCode))
+ {
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 OP Fail %X Size(%d) ",
+ resp->base.responseCode,
+ dataSize);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP2_FAIL
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 node
+ * @userdata2[0:31] responseCode
+ * @userdata2[32:63] dataSize
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP2_FAIL,
+ TARGETING::get_huid(
+ io_target.nodeTarget),
+ resp->base.responseCode,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+ else
+ {
+ // Walk the reponse data to pull the high order bytes out
+
+ if (resp->capData.capability != TPM_CAP_TPM_PROPERTIES ||
+ resp->capData.data.tpmProperties.count != 1 ||
+ resp->capData.data.tpmProperties.tpmProperty[0].property !=
+ TPM_PT_FIRMWARE_VERSION_2) {
+
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP2 FW INVALID DATA "
+ "Cap(%X) Cnt(%X) Prop(%X)",
+ resp->capData.capability,
+ resp->capData.data.tpmProperties.count,
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property);
+
+ /*@
+ * @errortype
+ * @reasoncode RC_TPM_GETCAP2_FW_INVALID_RESP
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_TPM_CMD_GETCAPFWVERSION
+ * @userdata1 node
+ * @userdata2[0:31] capability
+ * @userdata2[32:63] propery
+ * @devdesc Command failure reading TPM FW version.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ MOD_TPM_CMD_GETCAPFWVERSION,
+ RC_TPM_GETCAP2_FW_INVALID_RESP,
+ TARGETING::get_huid(
+ io_target.nodeTarget),
+ ((uint64_t)resp->capData.capability << 32) |
+ resp->capData.data.tpmProperties.
+ tpmProperty[0].property,
+ true /*Add HB SW Callout*/ );
+
+ err->collectTrace( SECURE_COMP_NAME );
+ break;
+ }
+ else
+ {
+ fwVersion[2] =
+ (resp->capData.data.tpmProperties.
+ tpmProperty[0].value >> 16);
+ fwVersion[3] =
+ (resp->capData.data.tpmProperties.
+ tpmProperty[0].value & 0xFFFF);
+ }
+ // Trace the response
+ TRACFCOMP( g_trac_trustedboot,
+ "TPM GETCAP FW Level %d.%d.%d.%d",
+ fwVersion[0],fwVersion[1],fwVersion[2],fwVersion[3]
+ );
+ }
+
+
+ } while ( 0 );
+
+
+ TRACDCOMP( g_trac_trustedboot,
+ EXIT_MRK"tpmCmdGetCapFwVersion() - %s",
+ ((NULL == err) ? "No Error" : "With Error") );
+ return err;
+}
+
+
+
+
+} // end TRUSTEDBOOT
OpenPOWER on IntegriCloud