diff options
author | Chris Engel <cjengel@us.ibm.com> | 2015-04-22 16:53:47 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-11-05 23:43:14 -0600 |
commit | 5c6ea674b20398ce999f64f8c7cde4292b104690 (patch) | |
tree | 60aacaeeeaeba6a369176a33c1a639a490e80288 /src/usr/secureboot/trusted | |
parent | 70e665f85f3e3ec8b118310884640a44ce83b7f2 (diff) | |
download | talos-hostboot-5c6ea674b20398ce999f64f8c7cde4292b104690.tar.gz talos-hostboot-5c6ea674b20398ce999f64f8c7cde4292b104690.zip |
Trusted boot support for performing TPM_STARTUP during isteps
Support added for TPM DD2.0
Added call to host_update_master_tpm during host_discover_targets istep
host_update_master_tpm istep performs TPM_STARTUP on TPM
Change-Id: Ie9c232ed6ecf72da58c40df726fe1deaec5af053
RTC: 125287
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18075
Tested-by: Jenkins Server
Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com>
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Reviewed-by: Timothy R. Block <block@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/secureboot/trusted')
-rw-r--r-- | src/usr/secureboot/trusted/makefile | 31 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.C | 248 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/trustedboot.H | 94 |
3 files changed, 371 insertions, 2 deletions
diff --git a/src/usr/secureboot/trusted/makefile b/src/usr/secureboot/trusted/makefile new file mode 100644 index 000000000..00991ed0f --- /dev/null +++ b/src/usr/secureboot/trusted/makefile @@ -0,0 +1,31 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/secureboot/trusted/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 = secureboot_trusted + +OBJS += $(if $(CONFIG_TPMDD),trustedboot.o,) + +CFLAGS += -iquote ../ +include ${ROOTPATH}/config.mk diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C new file mode 100644 index 000000000..507826c57 --- /dev/null +++ b/src/usr/secureboot/trusted/trustedboot.C @@ -0,0 +1,248 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/secureboot/trustedboot.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 trustedboot.C + * + * @brief Trusted boot 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 <secureboot/trustedboot_reasoncodes.H> + +// ---------------------------------------------- +// Trace definitions +// ---------------------------------------------- +trace_desc_t* g_trac_trustedboot = NULL; +TRAC_INIT( & g_trac_trustedboot, "TRBOOT", KILOBYTE ); + +// Easy macro replace for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) + +namespace TRUSTEDBOOT +{ + +void* host_update_master_tpm( void *io_pArgs ) +{ + errlHndl_t err = NULL; + TRACDCOMP( g_trac_trustedboot, + ENTER_MRK"host_update_master_tpm()" ); + TRACUCOMP( g_trac_trustedboot, + ENTER_MRK"host_update_master_tpm()"); + + do + { + + // First time here so we need to clean out our data structure + memset(&tpmTargets, 0, + sizeof(TpmTarget) * TRUSTEDBOOT::MAX_SYSTEM_TPMS); + + + // Get a node Target + TARGETING::TargetService& tS = TARGETING::targetService(); + TARGETING::Target* nodeTarget = NULL; + tS.getMasterNodeTarget( nodeTarget ); + + if (nodeTarget == NULL) + break; + + // Skip this target if target is non-functional + if(!nodeTarget->getAttr<TARGETING::ATTR_HWAS_STATE>(). \ + functional) + { + continue; + } + + if (TPMDD::tpmPresence(nodeTarget, TPMDD::TPM_PRIMARY)) + { + tpmTargets[TPM_MASTER_INDEX].nodeTarget = nodeTarget; + tpmTargets[TPM_MASTER_INDEX].chip = TPMDD::TPM_PRIMARY; + tpmTargets[TPM_MASTER_INDEX].functional = true; + + // Initialize the TPM, this will mark it as non-functional on fail + tpmInitialize(tpmTargets[TPM_MASTER_INDEX]); + + } + + if (!tpmTargets[TPM_MASTER_INDEX].functional) + { + + /// @todo RTC:134913 Switch to redundant chip if redundant TPM avail + + // Master TPM not available + TRACFCOMP( g_trac_trustedboot, + "Master TPM Existence Fail"); + + /*@ + * @errortype + * @reasoncode RC_TPM_EXISTENCE_FAIL + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_HOST_UPDATE_MASTER_TPM + * @userdata1 node + * @userdata2 0 + * @devdesc No TPMs found in system. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_HOST_UPDATE_MASTER_TPM, + RC_TPM_EXISTENCE_FAIL, + TARGETING::get_huid(nodeTarget), + 0, + true /*Add HB SW Callout*/ ); + + err->collectTrace( SECURE_COMP_NAME ); + break; + } + + + } while ( 0 ); + + TRACDCOMP( g_trac_trustedboot, + EXIT_MRK"host_update_master_tpm() - %s", + ((NULL == err) ? "No Error" : "With Error") ); + return err; +} + + +void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target) +{ + errlHndl_t err = NULL; + uint8_t dataBuf[BUFSIZE]; + size_t dataSize = sizeof(dataBuf); + size_t cmdSize = 0; + + TRACDCOMP( g_trac_trustedboot, + ENTER_MRK"tpmInitialize()" ); + TRACUCOMP( g_trac_trustedboot, + ENTER_MRK"tpmInitialize() tgt=0x%X chip=%d", + TARGETING::get_huid(io_target.nodeTarget), + io_target.chip); + + do + { + // TPM Initialization sequence + + // Send the TPM startup command + // Build our command block for a startup + memset(dataBuf, 0, sizeof(dataBuf)); + + TRUSTEDBOOT::TPM_BaseOut* resp = + (TRUSTEDBOOT::TPM_BaseOut*)dataBuf; +#ifdef CONFIG_TPMDD_1_2 + TRUSTEDBOOT::TPM_2ByteIn* cmd = + (TRUSTEDBOOT::TPM_2ByteIn*)dataBuf; + + cmd->base.tag = TRUSTEDBOOT::TPM_TAG_RQU_COMMAND; + cmd->base.paramSize = sizeof (TRUSTEDBOOT::TPM_2ByteIn); + cmd->base.ordinal = TRUSTEDBOOT::TPM_ORD_Startup; + cmd->param = TRUSTEDBOOT::TPM_ST_CLEAR; + cmdSize = cmd->base.paramSize; +#elif defined(CONFIG_TPMDD_2_0) + 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; +#endif + + err = deviceRead(io_target.nodeTarget, + &dataBuf, + dataSize, + DEVICE_TPM_ADDRESS( io_target.chip, + TPMDD::TPM_OP_TRANSMIT, + cmdSize) ); + + if (NULL != err) + { + TRACFCOMP( g_trac_trustedboot, + "TPM STARTUP I2C Fail %X : ", + err->reasonCode() ); + break; + + } + else if (TRUSTEDBOOT::TPM_SUCCESS != resp->returnCode) + { + TRACFCOMP( g_trac_trustedboot, + "TPM STARTUP OP Fail %X : ", + resp->returnCode); + + /*@ + * @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->returnCode, + true /*Add HB SW Callout*/ ); + + err->collectTrace( SECURE_COMP_NAME ); + break; + } + + + } while ( 0 ); + + + // If the TPM failed we will mark it not functional + if (NULL != err) + { + io_target.functional = false; + // Log this failure + errlCommit(err, SECURE_COMP_ID); + } + + + TRACDCOMP( g_trac_trustedboot, + EXIT_MRK"tpmInitialize() - %s", + ((NULL == err) ? "No Error" : "With Error") ); + +} + +} // end TRUSTEDBOOT diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H index 93a48096d..0f7a323f8 100644 --- a/src/usr/secureboot/trusted/trustedboot.H +++ b/src/usr/secureboot/trusted/trustedboot.H @@ -40,10 +40,26 @@ namespace TRUSTEDBOOT enum { MAX_SYSTEM_TPMS = 2, + BUFSIZE = 256, + TPM_MASTER_INDEX = 0, ///< Index into tpmTargets array for master chip + TPM_REDUNDANT_INDEX = 1, ///< Index for redundant chip TPM }; +/// Track system TPM status +struct TpmTarget +{ + TARGETING::Target* nodeTarget; + TPMDD::tpm_chip_types_t chip; ///< Chip Pri vs Backup + uint8_t functional:1; ///< Is TPM currently functional +} tpmTargets[MAX_SYSTEM_TPMS]; + +/** + * @brief Initialize the targetted TPM + * @param[in/out] target Current TPM target structure +*/ +void tpmInitialize(TRUSTEDBOOT::TpmTarget & io_target); + -#ifdef CONFIG_TPMDD_1_2 // Command structures taken from TPM Main - Part3 commands v 1.2 rev116 /// Base of all incoming messages @@ -72,6 +88,8 @@ struct TPM_4ByteOut { uint32_t resp; } PACKED; +#ifdef CONFIG_TPMDD_1_2 + /// Incoming TPM_GetCapability structure struct TPM_GetCapabilityIn { TPM_BaseIn base; @@ -123,7 +141,79 @@ enum { }; -#endif // CONFIG_TPMDD_1_2 +#elif defined(CONFIG_TPMDD_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; + +/// 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 + + // TPM Properties + TPM_PT_MANUFACTURER = 0x00000105, + + // TPM Return Codes + TPM_SUCCESS = 0x000, + + TPM_RC_INITIALIZE = 0x100, + +}; + +#endif } // end TRUSTEDBOOT namespace |