Skip to content

Commit

Permalink
Secure Boot: Set trusted boot enabled in HDAT considering all nodes
Browse files Browse the repository at this point in the history
This change implements reporting of trusted boot status
to HDAT considering all nodes of the system. To avoid
inter-node communication, the check is done after the
HDAT TPM info is populated for all nodes. The logic goes
through all TPM Info HDAT records (for each node) and checks
whether the master TPM on each node is present and functional.
The result is aggregated into the trusted boot enabled bit on
the master node. The check is done after the separators have
been extended into TPM; this allows each primary TPM more
chances to fail before we say that it's functional.

Trusted boot enabled bit is reported as 1 if ALL primary
TPMs on ALL booting nodes are present and functional. It is
reported as 0 if at least one primary is not present or
not functional.

Change-Id: I926532efe85b33e95e50d84b0b5e4554852f0601
RTC: 191194
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59279
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Ilya Smirnov authored and dcrowell77 committed May 31, 2018
1 parent 27bbfd3 commit 6ebff9a
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 13 deletions.
107 changes: 107 additions & 0 deletions src/usr/isteps/istep21/call_host_start_payload.C
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <hbotcompid.H>
#include <sys/misc.h>
#include <targeting/common/util.H>
#include <targeting/targplatutil.H>
#include <pnor/pnorif.H>
#include <kernel/console.H>
#include <util/misc.H>
Expand All @@ -59,6 +60,8 @@
#include <sbeio/sbeioif.H>
#include <runtime/runtime.H>
#include <p9_stop_api.H>
#include "../hdat/hdattpmdata.H"
#include "hdatstructs.H"

#ifdef CONFIG_DRTM_TRIGGERING
#include <secureboot/drtm.H>
Expand Down Expand Up @@ -187,6 +190,104 @@ void* msg_handler(msg_q_t i_msgQ)
return nullptr;
}

/**
* Function to align the trustedboot status on all nodes
*/
errlHndl_t calcTrustedBootState()
{
errlHndl_t l_errl = nullptr;

do {

TARGETING::Target* l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget(l_sys);
assert(l_sys != nullptr, "Could not get sys target!");
auto l_hbInstanceMap = l_sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>();
const size_t l_hbInstanceCount = __builtin_popcount(l_hbInstanceMap);
if((l_hbInstanceCount < 2) ||
(!TARGETING::UTIL::isCurrentMasterNode()))
{
break; // No-op on single node systems and non-master nodes.
}

uint32_t l_instance = 0;
uint64_t l_hdatBaseAddr = 0;
uint64_t l_dataSizeMax = 0; //unused
uint64_t l_hdatInstanceCount = 0;
uint64_t l_hbrtDataAddr = 0;

l_errl = RUNTIME::get_host_data_section(RUNTIME::IPLPARMS_SYSTEM,
l_instance, // instance 0
l_hbrtDataAddr,
l_dataSizeMax);
if(l_errl)
{
break;
}

hdatSysParms_t* const l_hdatSysParms =
reinterpret_cast<hdatSysParms_t*>(l_hbrtDataAddr);

SysSecSets* const l_sysSecuritySettings =
reinterpret_cast<SysSecSets*>(&l_hdatSysParms->hdatSysSecuritySetting);

l_errl = RUNTIME::get_instance_count(RUNTIME::NODE_TPM_RELATED,
l_hdatInstanceCount);
if(l_errl)
{
break;
}

assert(l_hdatInstanceCount == l_hbInstanceCount,
"Inconsistent number of functional nodes reported");

for(l_instance = 0; l_instance < l_hdatInstanceCount; ++l_instance)
{
l_errl = RUNTIME::get_host_data_section(RUNTIME::NODE_TPM_RELATED,
l_instance,
l_hdatBaseAddr,
l_dataSizeMax);
if(l_errl)
{
break;
}

auto const l_hdatTpmData = reinterpret_cast<HDAT::hdatTpmData_t*>
(l_hdatBaseAddr);
auto const l_hdatTpmInfo =
reinterpret_cast<HDAT::hdatHDIFDataArray_t*>
(reinterpret_cast<uint64_t>(l_hdatTpmData) +
l_hdatTpmData->hdatSbTpmInfo.hdatOffset);
auto const l_hdatTpmInstInfo =
reinterpret_cast<HDAT::hdatSbTpmInstInfo_t*>(
reinterpret_cast<uint64_t>(l_hdatTpmInfo) +
sizeof(*l_hdatTpmInfo));
TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace,
"calcTrustedBootState: l_hdatTpmInstInfo:",
l_hdatTpmInstInfo, sizeof(*l_hdatTpmInstInfo));
TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"calcTrustedBootState: Primary TPM's functional status ="
" %d", l_hdatTpmInstInfo->hdatFunctionalStatus);

if(l_hdatTpmInstInfo->hdatFunctionalStatus ==
HDAT::TpmPresentAndFunctional)
{
l_sysSecuritySettings->trustedboot &= 1;
}
else
{
l_sysSecuritySettings->trustedboot &= 0;
}
}

TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
"calcTrustedBootState: final trusted boot enabled status = %d",
l_sysSecuritySettings->trustedboot);

} while(0);

return l_errl;
}

void* call_host_start_payload (void *io_pArgs)
{
Expand All @@ -210,6 +311,12 @@ void* call_host_start_payload (void *io_pArgs)
break;
}

l_errl = calcTrustedBootState();
if(l_errl)
{
break;
}

msg_q_t l_msgQ = msg_q_create();

// Register event to be called on shutdown
Expand Down
1 change: 1 addition & 0 deletions src/usr/isteps/istep21/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/
EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/
EXTRAINCDIR += ${ROOTPATH}/src/usr/runtime/

OBJS += call_host_runtime_setup.o
OBJS += freqAttrData.o
Expand Down
1 change: 1 addition & 0 deletions src/usr/runtime/hdatservice.C
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,7 @@ errlHndl_t hdatService::getInstanceCount(const SectionId i_section,
switch(i_section)
{
case RUNTIME::PCRD:
case RUNTIME::NODE_TPM_RELATED:
{
hdat5Tuple_t* tuple = nullptr;
errhdl = getAndCheckTuple(i_section, tuple);
Expand Down
17 changes: 17 additions & 0 deletions src/usr/runtime/hdatstructs.H
Original file line number Diff line number Diff line change
Expand Up @@ -438,4 +438,21 @@ struct hdatCpuCtrlInfo_t
hdatCpuCtrlPair_t servRoutineData; // Service Routines Data Area
} __attribute__ ((packed));

/**
* @brief Structure to reflect the security settings on a system.
*/
typedef struct sysSecSets
{
// bit 0: Code Container Digital Signature Checking
uint16_t secureboot : 1;
// bit 1: Primary TPM is present and functional if single-node system;
// All primary TPMs are present and functional if multi-node system.
uint16_t trustedboot : 1;
// bit 2: SBE Security Backdoor bit.
// NOTE: This bit is labeled "Platform Security Overrides Allowed"
// in the section 6.1.1 of HDAT spec.
uint16_t sbeSecBackdoor : 1;
uint16_t reserved : 13;
} SysSecSets;

#endif
22 changes: 9 additions & 13 deletions src/usr/runtime/populate_hbruntime.C
Original file line number Diff line number Diff line change
Expand Up @@ -1461,19 +1461,6 @@ errlHndl_t populate_hbSecurebootData ( void )
hdatSysParms_t* const l_sysParmsPtr
= reinterpret_cast<hdatSysParms_t*>(l_hbrtDataAddr);

typedef struct sysSecSets
{
// bit 0: Code Container Digital Signature Checking
uint16_t secureboot : 1;
// bit 1: Measurements Extended to Secure Boot TPM
uint16_t trustedboot : 1;
// bit 2: SBE Security Backdoor bit.
// NOTE: This bit is labeled "Platform Security Overrides Allowed"
// in the section 6.1.1 of HDAT spec.
uint16_t sbeSecBackdoor : 1;
uint16_t reserved : 13;
} SysSecSets;

// populate system security settings in hdat
SysSecSets* const l_sysSecSets =
reinterpret_cast<SysSecSets*>(&l_sysParmsPtr->hdatSysSecuritySetting);
Expand Down Expand Up @@ -1703,6 +1690,15 @@ errlHndl_t populate_TpmInfoByNode(const uint64_t i_instance)
TARGETING::TargetHandleList tpmList;
TRUSTEDBOOT::getTPMs(tpmList, TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);

// Put the primary TPM first in the list of TPMs to simplify alignment of
// trusted boot enabled bits across the nodes.
std::sort(tpmList.begin(), tpmList.end(),
[](TARGETING::TargetHandle_t lhs, TARGETING::TargetHandle_t rhs)
{
return (lhs->getAttr<TARGETING::ATTR_TPM_ROLE>() ==
TARGETING::TPM_ROLE_TPM_PRIMARY);
});

TARGETING::TargetHandleList l_procList;

getAllChips(l_procList,TARGETING::TYPE_PROC,false);
Expand Down

0 comments on commit 6ebff9a

Please sign in to comment.