summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2017-01-25 13:10:08 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-02-02 15:06:55 -0500
commita42bbccdd949bc4b78e856087019c73a126420d4 (patch)
tree5fdc402c77c9578d3ddbcd4095cfe887f0f44cf6
parent31591a027b6d76be0cd081d3bcce2e746fdc7623 (diff)
downloadtalos-hostboot-a42bbccdd949bc4b78e856087019c73a126420d4.tar.gz
talos-hostboot-a42bbccdd949bc4b78e856087019c73a126420d4.zip
Support extending sections to PCRs
- Ported p8 secureboot PCR extension code Change-Id: I2bbf6ee6b2980c2fbe32dfb9cad25e9e2aba3285 RTC: 167581 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35632 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
-rw-r--r--src/include/runtime/interface.h12
-rw-r--r--src/include/usr/secureboot/header.H11
-rw-r--r--src/include/usr/secureboot/service.H24
-rw-r--r--src/usr/devtree/bld_devtree.C2
-rw-r--r--src/usr/pnor/pnor_common.C45
-rw-r--r--src/usr/pnor/pnor_common.H5
-rw-r--r--src/usr/pnor/pnorrp.C35
-rw-r--r--src/usr/secureboot/base/header.C85
-rw-r--r--src/usr/secureboot/base/securerom.C66
-rw-r--r--src/usr/secureboot/base/securerom.H28
-rw-r--r--src/usr/secureboot/base/service.C2
-rw-r--r--src/usr/secureboot/base/test/secureromtest.H8
-rw-r--r--src/usr/secureboot/runtime/rt_secureboot.C14
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C200
-rw-r--r--src/usr/secureboot/trusted/trustedboot.C2
-rw-r--r--src/usr/secureboot/trusted/trustedboot.H4
16 files changed, 402 insertions, 141 deletions
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h
index 6681e49ca..f5eb2cba1 100644
--- a/src/include/runtime/interface.h
+++ b/src/include/runtime/interface.h
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -655,10 +655,10 @@ typedef struct runtimeInterfaces
* Must not be NULL. Container is assumed to be stripped of any ECC
* and must start with a valid secure header (which contains the
* container size information)
- * @param[in] i_pHwHashKey Pointer to a valid hardware hash key.
+ * @param[in] i_pHwKeyHash Pointer to a valid hardware keys' hash.
* Must not be NULL.
- * @param[in] i_hwHashKeySize Size of the hardware hash key.
- * A value which incorrectly states the size of the hardware hash key
+ * @param[in] i_hwKeyHashSize Size of the hardware keys' hash.
+ * A value which incorrectly states the size of the hardware keys' hash
* will be detected as a verification error or worse, an illegal memory
* access. Must not be 0.
* @note If secureboot is compiled out, the function pointer will be set to
@@ -672,8 +672,8 @@ typedef struct runtimeInterfaces
*/
int (*verify_container)(
const void* i_pContainer,
- const void* i_pHwHashKey,
- size_t i_hwHashKeySize);
+ const void* i_pHwKeyHash,
+ size_t i_hwKeyHashSize);
// Reserve some space for future growth.
// do NOT ever change this number, even if you add functions.
diff --git a/src/include/usr/secureboot/header.H b/src/include/usr/secureboot/header.H
index f7a5121c6..4ad1f0e7e 100644
--- a/src/include/usr/secureboot/header.H
+++ b/src/include/usr/secureboot/header.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -59,10 +59,8 @@ namespace SECUREBOOT
iv_data=NULL;
}
- // TODO securebootp9 This is from p9 code. See the corresponding
- // comment in header.C for more info.
- /** @brief Extract header from original HRMOR - 1 page address. */
- void loadBaseHeader();
+ // @TODO RTC 168021 Converge to single method of reading
+ // secure header
/**
* @brief Extracts base image (HBB) header (ECC removed) from
@@ -73,6 +71,9 @@ namespace SECUREBOOT
*/
void loadSecurely();
+ // @TODO RTC 168021 Converge to single method of reading
+ // secure header
+
/**
* @brief Caches non-secure PNOR copy of the base image (HBB)
* header (ECC removed) to support extending HBB measurements
diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H
index 99772b429..afb3ed934 100644
--- a/src/include/usr/secureboot/service.H
+++ b/src/include/usr/secureboot/service.H
@@ -28,9 +28,13 @@
#include <errl/errlentry.H>
#include <config.h>
#include <secureboot/settings.H>
+#include <utility>
#include <cstdint>
typedef uint8_t SHA512_t[64];
+
+typedef std::vector< std::pair<void*,size_t> > blobPair_t;
+
/* From sha512.h: */
#define SHA512_DIGEST_LENGTH 64
typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ \
@@ -160,12 +164,26 @@ namespace SECUREBOOT
errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf);
/**
- * @brief Retrieve the internal hardware hash key from secure ROM
- * object.
+ * @brief Retrieve the internal hardware keys' hash used to validate
+ * containers
* @param[out] o_hash Reference to the sha2_hash_t array to copy the
* hash to.
*/
- void getHwHashKeys(sha2_hash_t o_hash);
+ void getHwKeyHash(sha2_hash_t o_hash);
+
+ /*
+ * @brief Hash the concatenation of N Blobs
+ *
+ * Asserts if any blob pointer is NULL
+ *
+ * @param[in] i_blobs Vector of pairs composed of a void
+ * pointer to effective address and size
+ * of the blob to concatenate
+ * @param[out] o_buf SHA512 hash
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf);
/**
* @brief Common secureboot handler for secureboot failures.
diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C
index 791e9a79a..ec2237f3f 100644
--- a/src/usr/devtree/bld_devtree.C
+++ b/src/usr/devtree/bld_devtree.C
@@ -2279,7 +2279,7 @@ errlHndl_t bld_fdt_secureboot(devTree * i_dt, bool i_smallTree)
dtOffset_t secBootNode = i_dt->addNode(rootNode, "ibm,secureboot");
sha2_hash_t hw_key_hash;
- SECUREBOOT::getHwHashKeys(hw_key_hash);
+ SECUREBOOT::getHwKeyHash(hw_key_hash);
i_dt->addPropertyBytes(secBootNode, "hw-key-hash",
reinterpret_cast<uint8_t*>(hw_key_hash),
diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C
index 351386256..2414a15c2 100644
--- a/src/usr/pnor/pnor_common.C
+++ b/src/usr/pnor/pnor_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2017 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -298,28 +298,31 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC)
}
- if (o_TOC[l_secId].version == FFS_VERS_SHA512)
+ // @TODO RTC 168021 Remove legacy extensions when all
+ // secure sections are supported
+ auto isSecure = PNOR::isSecureSection(l_secId);
+ if ( o_TOC[l_secId].version == FFS_VERS_SHA512
+ && !isSecure)
{
- TRACFCOMP(g_trac_pnor, "PNOR::parseTOC: Incrementing"
- " Flash Address for SHA Header");
- uint32_t l_addr = o_TOC[l_secId].flashAddr;
- size_t l_headerSize = 0;
- if (o_TOC[l_secId].integrity == FFS_INTEG_ECC_PROTECT)
- {
- l_headerSize = PAGESIZE_PLUS_ECC;
- }
- else
- {
- l_headerSize = PAGESIZE;
- }
- l_errhdl = PNOR::extendHash(l_addr, l_headerSize,
- cv_EYECATCHER[l_secId]);
- if (l_errhdl)
- {
- break;
- }
+ // For non-secure sections with a SHA512 header, the
+ // flash address has incremented past the header, so
+ // back up by the header size (accounting for ECC) in order
+ // to extend the header
+ auto addr = o_TOC[l_secId].flashAddr;
+ size_t headerSize =
+ (o_TOC[l_secId].integrity == FFS_INTEG_ECC_PROTECT) ?
+ PAGESIZE_PLUS_ECC : PAGESIZE;
+ addr -= headerSize;
+
+ l_errhdl = PNOR::extendHash(addr, headerSize,
+ cv_EYECATCHER[l_secId]);
+ if (l_errhdl)
+ {
+ break;
+ }
}
}
+
for(int tmpId = 0;
tmpId < PNOR::NUM_SECTIONS;
tmpId ++ )
@@ -335,6 +338,8 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC)
return l_errhdl;
}
+// @TODO RTC 168021 Remove legacy extensions when all secure sections are
+// supported
errlHndl_t PNOR::extendHash(uint64_t i_addr, size_t i_size, const char* i_name)
{
errlHndl_t l_errhdl = NULL;
diff --git a/src/usr/pnor/pnor_common.H b/src/usr/pnor/pnor_common.H
index e8b6bd4f8..497e85e83 100644
--- a/src/usr/pnor/pnor_common.H
+++ b/src/usr/pnor/pnor_common.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -73,6 +73,9 @@ namespace PNOR {
void physicalToMmioOffset(uint64_t i_hbbAddress,
uint64_t& o_mmioOffset);
+ // @TODO RTC 168021 Remove legacy extensions when all secure sections
+ // are supported via story 168021
+
/**
* @brief Reads version header of section, hashes it, and extends to tpm
* buffer list.
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 827765551..15739c3bc 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -329,29 +329,34 @@ void PnorRP::initDaemon()
break;
}
+ // @TODO RTC 168021 Remove the non-secure extension path and
+ // always used the converged HBB extension path.
+
+ // If secured, extend base image (HBB) when Hostboot first starts.
+ // Since HBB is never re-loaded, inhibit extending this image in
+ // runtime code.
#ifndef __HOSTBOOT_RUNTIME
#ifdef CONFIG_SECUREBOOT
- if(!SECUREBOOT::enabled())
+ //TODO: RTC 167581
+ // When RTC 166848 is available, add restrictions back in when
+ // base image header copy availability is detected
+ // if(!SECUREBOOT::enabled())
{
-
- // If in secure mode, we already have securely obtained the header
- // because we copied it before the blind purge. In non-secure mode,
- // cache the header from PNOR (susceptible to attacks). This is ok
- // because there are already no security guarantees in non-secure
- // mode. We need to get the HBB address separately because the
- // OC ignores the header
+ // If compliant bootloader was present, it saved the HBB header
+ // to a known location accessible to HBB. Until that bootloader
+ // is widely distributed, when in non-secure mode in lab,
+ // manufacturing, etc., read the header directly from PNOR.
PNOR::SideInfo_t pnorInfo = {PNOR::WORKING};
l_errhdl = PnorRP::getSideInfo(PNOR::WORKING, pnorInfo);
- if(l_errhdl != NULL)
+ if(l_errhdl != nullptr)
{
break;
}
- const SectionData_t* pHbb = &iv_TOC[PNOR::HB_BASE_CODE];
- bool ecc = (pHbb->integrity == FFS_INTEG_ECC_PROTECT) ? true :false;
+ const SectionData_t* const pHbb = &iv_TOC[PNOR::HB_BASE_CODE];
+ const bool ecc = (pHbb->integrity == FFS_INTEG_ECC_PROTECT) ?
+ true :false;
- // We have to read two pages because the secure header is a page by
- // itself, but it is prefixed by the SBE header
uint8_t pHeader[PAGESIZE] = {0};
uint64_t fatalError = 0;
l_errhdl = readFromDevice(
@@ -364,12 +369,12 @@ void PnorRP::initDaemon()
// If fatalError != 0 there is an uncorrectable ECC error (UE).
// In that case, continue on with inaccurate data, as
// readFromDevice API will initiate a shutdown
- if(l_errhdl != NULL)
+ if(l_errhdl != nullptr)
{
break;
}
- // Skip the SBE header on the HBB image to get the real header
+ // Cache the header
(void)SECUREBOOT::baseHeader().setNonSecurely(
pHeader);
}
diff --git a/src/usr/secureboot/base/header.C b/src/usr/secureboot/base/header.C
index 37ba7ca72..4aba9481f 100644
--- a/src/usr/secureboot/base/header.C
+++ b/src/usr/secureboot/base/header.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,6 +26,7 @@
#include <sys/mm.h>
#include <sys/mmio.h>
#include <kernel/console.H>
+#include <errno.h>
namespace SECUREBOOT
{
@@ -34,53 +35,65 @@ namespace SECUREBOOT
return Singleton<Header>::instance();
}
- // TODO securebootp9 this implementation native to p9 appears to be doing
- // approximately the same thing as p8's loadSecurely() method. We need to
- // confirm and merge together or leave separate and merely remove comment.
- void Header::loadBaseHeader()
+ // @TODO RTC 168021 Converge on a single method of reading the secure
+ // header
+ void Header::loadSecurely()
{
- // Calculate original address of the secureboot header.
- // Zero is purposefully not mapped into the VMM tables, so we
- // can't use that for the virtual-to-real translation. Since
- // this object is in the base image, EA = HRMOR | PA, so we can
- // use PA - EA to find the HRMOR.
- uint64_t addr = mm_virt_to_phys(this) -
- reinterpret_cast<uint64_t>(this);
- addr -= PAGESIZE;
-
- // Map in the header.
- void* origHeader = mm_block_map(reinterpret_cast<void*>(addr),
- PAGESIZE);
-
- // Copy header to a save area.
- // In the future we might want to just extract pieces of the
- // header. The header is important when we start updating
- // the TPM PCRs.
- iv_data = malloc(PAGESIZE);
- memcpy(iv_data, origHeader, PAGESIZE);
-
- // Unmap the header.
- mm_block_unmap(origHeader);
+ //@TODO RTC 167581
+ // When RTC 166848 is available, pull in real header
return;
}
- // TODO securebootp9 this implementation of the follwoing two methods need
- // to be added based on p8 code
- void Header::loadSecurely()
- {
- }
-
+ // @TODO RTC 168021 Converge on a single method of reading the secure
+ // header
void Header::setNonSecurely(
- const void* i_pHeader)
+ const void* const i_pHeader)
{
+ // Fatal code bug if already loaded
+ assert(iv_data == nullptr,"BUG! In setNonSecurely(), "
+ "a cached header is already present.");
+
+ // Fatal code bug if called with nullptr pointer
+ assert(i_pHeader != nullptr,"BUG! In setNonSecurely(), "
+ "caller passed a nullptr header.");
+
+ iv_data = calloc(1,PAGESIZE);
+ memcpy(iv_data,i_pHeader,PAGE_SIZE);
}
void Header::getHeader(
- const void*& o_pHeader ) const
+ const void*& o_pHeader) const
{
// Fatal code bug if queried before loaded
- assert(iv_data!=nullptr);
+ assert(iv_data!=nullptr,"BUG! In getHeader(), "
+ "header is not present.");
o_pHeader = iv_data;
}
+
+ void Header::_calcSecureLoadAddr(
+ const void*& o_pCode) const
+ {
+ //@TODO RTC 167581
+ // When RTC 166848 is available, pull in real header
+
+ // Determine the secure address where the HBB image was loaded by SBE.
+ // Regardless of whether security is enabled or not, HBB always ends up
+ // at the secure load address (which corresponds to the HRMOR).
+ //
+ // Zero is purposefully not mapped into the VMM tables, so we
+ // can't use that for the virtual-to-real translation. Since
+ // this object is in the base (HBB) image, PA = HRMOR | EA, so we can
+ // use PA - EA to find the HRMOR.
+ const void* hrmor = reinterpret_cast<const void*>(
+ mm_virt_to_phys(
+ const_cast<SECUREBOOT::Header*>(this)) -
+ reinterpret_cast<uint64_t>(this));
+
+ // HRMOR lookup should never fail
+ assert( reinterpret_cast<uint64_t>(hrmor)
+ != static_cast<uint64_t>(-EFAULT));
+
+ o_pCode = hrmor;
+ }
}
diff --git a/src/usr/secureboot/base/securerom.C b/src/usr/secureboot/base/securerom.C
index dd1428f33..74c2a18bb 100644
--- a/src/usr/secureboot/base/securerom.C
+++ b/src/usr/secureboot/base/securerom.C
@@ -84,20 +84,27 @@ errlHndl_t verifyContainer(void * i_container, const sha2_hash_t* i_hwKeyHash)
errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf)
{
return Singleton<SecureROM>::instance().hashBlob(i_blob, i_size, io_buf);
+}
+/**
+ * @brief Hash concatenation of 2 Blobs
+ *
+ */
+errlHndl_t hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf)
+{
+ return Singleton<SecureROM>::instance().hashConcatBlobs(i_blobs, o_buf);
}
/*
- * @brief Externally available hardware hash key function
+ * @brief Externally available hardware keys' hash retrieval function
*/
-void getHwHashKeys(sha2_hash_t o_hash)
+void getHwKeyHash(sha2_hash_t o_hash)
{
- return Singleton<SecureROM>::instance().getHwHashKeys(o_hash);
+ return Singleton<SecureROM>::instance().getHwKeyHash(o_hash);
}
}; //end SECUREBOOT namespace
-
/********************
Public Methods
********************/
@@ -259,13 +266,13 @@ errlHndl_t SecureROM::initialize()
/* Retrieve HW Hash Keys From The System */
/***************************************************************/
- // @todo RTC:RTC:34080 - Support for SecureROM::getHwHashKeys()
- l_errl = SecureROM::getHwHashKeys();
+ // @todo RTC:RTC:34080 - Support for SecureROM::getHwKeyHash()
+ l_errl = SecureROM::getHwKeyHash();
if (l_errl != NULL)
{
TRACFCOMP(g_trac_secure,ERR_MRK"SecureROM::initialize():"
- " SecureROM::getHwHashKeys() returned an error");
+ " SecureROM::getHwKeyHash() returned an error");
l_errl->collectTrace(SECURE_COMP_NAME,256);
break;
@@ -329,8 +336,8 @@ errlHndl_t SecureROM::verifyContainer(void * i_container,
// struct elements my_ecid, entry_point and log
memset(&l_hw_parms, 0, sizeof(ROM_hw_params));
- // Now set hw_key_hash, which is of type sha2_hash_t, to iv_hash_key
- memcpy (&l_hw_parms.hw_key_hash, &iv_hash_key, sizeof(sha2_hash_t));
+ // Now set hw_key_hash, which is of type sha2_hash_t, to iv_key_hash
+ memcpy (&l_hw_parms.hw_key_hash, &iv_key_hash, sizeof(sha2_hash_t));
TRACFBIN(g_trac_secure,"SecureROM::verifyContainer(): hw_key_hash",
l_hw_parms.hw_key_hash, sizeof(sha2_hash_t));
@@ -384,6 +391,7 @@ errlHndl_t SecureROM::verifyContainer(void * i_container,
/*@
* @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
* @moduleid SECUREBOOT::MOD_SECURE_ROM_VERIFY
* @reasoncode SECUREBOOT::RC_ROM_VERIFY
* @userdata1 l_rc
@@ -457,6 +465,28 @@ errlHndl_t SecureROM::hashBlob(const void * i_blob, size_t i_size, SHA512_t io_b
return l_errl;
}
+/**
+ * @brief Hash concatenation of N Blobs
+ */
+errlHndl_t SecureROM::hashConcatBlobs(const blobPair_t &i_blobs,
+ SHA512_t o_buf) const
+{
+ errlHndl_t pError = nullptr;
+ std::vector<uint8_t> concatBuf;
+ for (const auto &it : i_blobs)
+ {
+ assert(it.first != nullptr, "BUG! In SecureROM::hashConcatBlobs(), "
+ "User passed in nullptr blob pointer");
+ const uint8_t* const blob = static_cast<const uint8_t*>(it.first);
+ const auto blobSize = it.second;
+ concatBuf.insert(concatBuf.end(), blob, blob + blobSize);
+ }
+
+ // Call hash blob on new concatenated buffer
+ pError = hashBlob(concatBuf.data(),concatBuf.size(),o_buf);
+
+ return pError;
+}
/********************
Internal Methods
@@ -470,8 +500,8 @@ SecureROM::SecureROM()
{
TRACDCOMP(g_trac_secure, "SecureROM::SecureROM()>");
- // Clear out iv_hash_keys, which is of type sha2_hash_t
- memset(&iv_hash_key, 0, sizeof(sha2_hash_t) );
+ // Clear out iv_key_hash, which is of type sha2_hash_t
+ memset(&iv_key_hash, 0, sizeof(sha2_hash_t) );
}
@@ -547,26 +577,26 @@ void SecureROM::_cleanup()
/**
- * @brief Retrieves HW Keys from the system
+ * @brief Retrieves HW keys' hash from the system
*/
-errlHndl_t SecureROM::getHwHashKeys()
+errlHndl_t SecureROM::getHwKeyHash()
{
errlHndl_t l_errl = NULL;
- TRACFCOMP(g_trac_secure,INFO_MRK"SecureROM::getHwHashKeys() NOT supported");
+ TRACFCOMP(g_trac_secure,INFO_MRK"SecureROM::getHwKeyHash() NOT supported");
- // @todo RTC:34080 - Add support for getting HW Hash Keys from System
+ // @todo RTC:34080 - Add support for getting HW keys' hash from System
return l_errl;
}
/**
- * @brief Retrieve the internal hardware hash key from secure ROM object.
+ * @brief Retrieve the internal hardware keys' hash from secure ROM object.
*/
-void SecureROM::getHwHashKeys(sha2_hash_t o_hash)
+void SecureROM::getHwKeyHash(sha2_hash_t o_hash)
{
- memcpy(o_hash, iv_hash_key, sizeof(sha2_hash_t));
+ memcpy(o_hash, iv_key_hash, sizeof(sha2_hash_t));
}
/**
diff --git a/src/usr/secureboot/base/securerom.H b/src/usr/secureboot/base/securerom.H
index 4bb4fd54e..3704209d9 100644
--- a/src/usr/secureboot/base/securerom.H
+++ b/src/usr/secureboot/base/securerom.H
@@ -71,13 +71,28 @@ class SecureROM
errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf) const;
/**
- * @brief Retrieve the internal hardware hash key from secure ROM
+ * @brief Retrieve the internal hardware keys' hash from secure ROM
* object.
*
* @param[out] o_hash Reference to the sha2_hash_t array to copy the
* hash to.
*/
- void getHwHashKeys(sha2_hash_t o_hash);
+ void getHwKeyHash(sha2_hash_t o_hash);
+
+ /*
+ * @brief Hash the concatenation of N Blobs
+ *
+ * Asserts if any blob pointer is NULL
+ *
+ * @param[in] i_blobs Vector of pairs composed of a void
+ * pointer to effective address and size
+ * of the blob to concatenate
+ * @param[out] o_buf SHA512 hash
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t hashConcatBlobs (const blobPair_t &i_blobs,
+ SHA512_t o_buf) const;
protected:
@@ -104,21 +119,20 @@ class SecureROM
void * iv_device_ptr;
/**
- * Hash Key Retrieved From System
+ * HW key' hash retrieved from system
*/
- sha2_hash_t iv_hash_key;
-
+ sha2_hash_t iv_key_hash;
/********************************************
* Private Functions
********************************************/
/**
- * @brief Retrieves HW Keys from the system
+ * @brief Retrieves HW keys' hash from the system
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t getHwHashKeys();
+ errlHndl_t getHwKeyHash();
/**
* @brief Static instance function for testcase only
diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C
index beed71616..6a8a35935 100644
--- a/src/usr/secureboot/base/service.C
+++ b/src/usr/secureboot/base/service.C
@@ -68,7 +68,7 @@ void* initializeBase(void* unused)
// Load original secureboot header.
if (enabled())
{
- Singleton<Header>::instance().loadBaseHeader();
+ Singleton<Header>::instance().loadSecurely();
}
// Extend memory footprint into lower portion of cache.
diff --git a/src/usr/secureboot/base/test/secureromtest.H b/src/usr/secureboot/base/test/secureromtest.H
index 805b5bc2b..8a4ff4043 100644
--- a/src/usr/secureboot/base/test/secureromtest.H
+++ b/src/usr/secureboot/base/test/secureromtest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -62,7 +62,7 @@ void unloadSignedFile( void * & io_signedFile_pageAddr,
// secureboot_signed_container was generated using this hw hash key. If another
// key is in pibmem, this test will always fail.
-const uint64_t hw_hash_key[] =
+const uint64_t hw_key_hash[] =
{
0x40d487ff7380ed6a,
0xd54775d5795fea0d,
@@ -129,8 +129,8 @@ class SecureROMTest : public CxxTest::TestSuite
return;
}
- // Set hw hash key
- memcpy (& l_sRom.iv_hash_key, &hw_hash_key, sizeof(sha2_hash_t));
+ // Set hardware keys' hash
+ memcpy (& l_sRom.iv_key_hash, &hw_key_hash, sizeof(sha2_hash_t));
/*******************************************************************/
/* Call verify function */
diff --git a/src/usr/secureboot/runtime/rt_secureboot.C b/src/usr/secureboot/runtime/rt_secureboot.C
index 8ab6d5e51..3b7626553 100644
--- a/src/usr/secureboot/runtime/rt_secureboot.C
+++ b/src/usr/secureboot/runtime/rt_secureboot.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,17 +38,17 @@ namespace SECUREBOOT
int verify_container(
const void* i_pContainer,
- const void* i_pHwHashKey,
- const size_t i_hwHashKeySize)
+ const void* i_pHwKeyHash,
+ const size_t i_hwKeyHashSize)
{
int rc = 0;
- SB_ENTER(
+ SB_ENTER(
"verify_container: "
"container ptr = %p, "
- "HW hash key ptr = %p, "
- "HW hash key size = %d",
- i_pContainer,i_pHwHashKey,i_hwHashKeySize);
+ "HW keys' hash ptr = %p, "
+ "HW keys' hash size = %d",
+ i_pContainer,i_pHwKeyHash,i_hwKeyHashSize);
// TODO: RTC 156485
// Implement guts of verify_container
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index dbb47b6e5..c4a149368 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,10 @@
#include <errl/errludstring.H>
#include <secureboot/trustedbootif.H>
#include <secureboot/trustedboot_reasoncodes.H>
+#include <secureboot/header.H>
+#include <secureboot/containerheader.H>
+#include <pnor/pnorif.H>
+#include <config.h>
#include "../trustedboot.H"
#include "../trustedbootCmds.H"
#include "../trustedbootUtils.H"
@@ -51,7 +55,7 @@
// Trace definitions
// ----------------------------------------------
#ifdef CONFIG_TPMDD
-trace_desc_t* g_trac_trustedboot = NULL;
+trace_desc_t* g_trac_trustedboot = nullptr;
TRAC_INIT( & g_trac_trustedboot, "TRBOOT", KILOBYTE );
#endif
@@ -59,6 +63,9 @@ namespace TRUSTEDBOOT
{
#ifdef CONFIG_TPMDD
+// Const string to append to PCR extension messages
+const char* const FW_KEY_HASH_EXT = " FW KEY HASH";
+
/// Global object to store TPM status
SystemTpms systemTpms;
@@ -255,26 +262,189 @@ errlHndl_t pcrExtend(TPM_Pcr i_pcr,
return err;
}
-errlHndl_t extendPnorSectionHash(const SECUREBOOT::ContainerHeader& i_conHdr,
- const void* i_vaddr,
- const PNOR::SectionId i_sec)
+errlHndl_t extendPnorSectionHash(
+ const SECUREBOOT::ContainerHeader& i_conHdr,
+ const void* const i_vaddr,
+ const PNOR::SectionId i_sec)
{
- errlHndl_t l_errhdl = NULL;
+ errlHndl_t pError = nullptr;
+
+#ifdef CONFIG_TPMDD
+
+ do {
+
+ PNOR::SectionInfo_t sectionInfo;
+ pError = PNOR::getSectionInfo(i_sec,sectionInfo);
+ if(pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
+ "getSectionInfo() with section ID = %d.",
+ i_sec);
+ break;
+ }
+
+ TRACDCOMP(g_trac_trustedboot, ENTER_MRK " extendPnorSectionHash for "
+ "section: %s",sectionInfo.name);
+
+ const size_t protectedSize = i_conHdr.payloadTextSize();
+
+ // Generate pcr extension message
+ char swKeyMsg[strlen(sectionInfo.name) + strlen(FW_KEY_HASH_EXT) + 1];
+ memset(swKeyMsg, 0, sizeof(swKeyMsg));
+ strcat(swKeyMsg,sectionInfo.name);
+ strcat(swKeyMsg,FW_KEY_HASH_EXT);
+
+ TPM_Pcr pnorHashPcr = PCR_0;
+ // PAYLOAD is the only section that needs its hash extended to PCR_4
+ if (i_sec == PNOR::PAYLOAD)
+ {
+ pnorHashPcr = PCR_4;
+ }
+ // Extend swKeyHash to the next PCR after the hash extension PCR.
+ const TPM_Pcr swKeyHashPcr = static_cast<TPM_Pcr>(pnorHashPcr + 1);
+
+ if (SECUREBOOT::enabled())
+ {
+ // If secureboot is enabled, use protected hash in header
+ pError = TRUSTEDBOOT::pcrExtend(pnorHashPcr,
+ reinterpret_cast<const uint8_t*>(i_conHdr.payloadTextHash()),
+ sizeof(SHA512_t),
+ sectionInfo.name);
+ if (pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
+ "pcrExtend() (extend payload text hash) for section %s.",
+ sectionInfo.name);
+ break;
+ }
+
+ // Extend SW public key hash
+ pError = TRUSTEDBOOT::pcrExtend(swKeyHashPcr,
+ reinterpret_cast<const uint8_t*>(i_conHdr.swKeyHash()),
+ sizeof(SHA512_t),
+ swKeyMsg);
+ if (pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
+ "pcrExtend() (extend SW public key hash) for section %s.",
+ sectionInfo.name);
+ break;
+ }
+ }
+ else
+ {
+ // If secureboot is not enabled, measure protected section
+ SHA512_t hash = {0};
+ SECUREBOOT::hashBlob(i_vaddr, protectedSize, hash);
+ pError = TRUSTEDBOOT::pcrExtend(pnorHashPcr, hash,
+ sizeof(SHA512_t),
+ sectionInfo.name);
+ if (pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK " Failed in call to "
+ "pcrExtend() (extend payload text) for section %s.",
+ sectionInfo.name);
+ break;
+ }
+ }
+
+ } while(0);
+
+ TRACDCOMP(g_trac_trustedboot, EXIT_MRK " extendPnorSectionHash");
- // TODO securebootp9
- // remove the following code and implement based on p8 code
- TRACFCOMP(g_trac_trustedboot, "ExtendPnorSectionHash called for section %d and "
- " address %.16llX with payload text size %i"
- "but not unimplemented in p9", i_sec, i_vaddr);
+#endif
- return l_errhdl;
+ return pError;
}
errlHndl_t extendBaseImage()
{
- errlHndl_t pError = NULL;
- // TODO securebootp9
- // implement extendBaseImage based on p8 code
+ errlHndl_t pError = nullptr;
+
+#ifdef CONFIG_TPMDD
+
+ TRACFCOMP(g_trac_trustedboot, ENTER_MRK " extendBaseImage()");
+
+ do {
+
+ // Query the HBB header and code address
+ const void* pHbbHeader = nullptr;
+
+ (void)SECUREBOOT::baseHeader().getHeader(
+ pHbbHeader);
+
+ // Fatal code bug if either address is nullptr
+ if(pHbbHeader == nullptr)
+ {
+ assert(false,"BUG! In extendBaseImage(), cached header address is "
+ "nullptr");
+ }
+
+ TRACDBIN(g_trac_trustedboot,"Base Header",pHbbHeader,
+ TRUSTEDBOOT::DEFAULT_BIN_TRACE_SIZE);
+
+ // TODO: RTC 168021
+ // Need to remove this when HBB has a secure header across all platforms
+ // -or- a more general compatibility mechanism has been created allowing
+ // some platforms to stage in support
+ if(!PNOR::cmpSecurebootMagicNumber(
+ reinterpret_cast<const uint8_t*>(pHbbHeader)))
+ {
+ TRACFCOMP(g_trac_trustedboot, INFO_MRK " HBB header is not a secure "
+ "header; inhibiting extending base image measurement");
+ break;
+ }
+
+ // Build a container header object from the raw header
+ const SECUREBOOT::ContainerHeader hbbContainerHeader(pHbbHeader);
+
+ const void* pHbbVa = nullptr;
+ if(!SECUREBOOT::enabled())
+ {
+ PNOR::SectionInfo_t l_info;
+
+ // @TODO RTC 168021 Remove this path since header will always be
+ // cached
+ pError = getSectionInfo(PNOR::HB_BASE_CODE, l_info);
+ if(pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK "Failed in call to "
+ "getSectionInfo for HBB section");
+ break;
+ }
+
+ if(l_info.vaddr == 0)
+ {
+ assert(false,"BUG! In extendBaseImage(), HBB virtual address "
+ "was 0");
+ }
+
+ pHbbVa = reinterpret_cast<const void*>(
+ l_info.vaddr);
+
+ TRACDBIN(g_trac_trustedboot,"PNOR Base Code",pHbbVa,
+ TRUSTEDBOOT::DEFAULT_BIN_TRACE_SIZE);
+ }
+
+ // Extend the HBB measurement to the TPM
+ pError = extendPnorSectionHash(
+ hbbContainerHeader,
+ pHbbVa,
+ PNOR::HB_BASE_CODE);
+
+ if(pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK "Failed in call to "
+ "extendPnorSectionHash() for HBB section.");
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_trustedboot, EXIT_MRK " extendBaseImage()");
+
+#endif
+
return pError;
}
diff --git a/src/usr/secureboot/trusted/trustedboot.C b/src/usr/secureboot/trusted/trustedboot.C
index a7b7f8c56..b6bbd313b 100644
--- a/src/usr/secureboot/trusted/trustedboot.C
+++ b/src/usr/secureboot/trusted/trustedboot.C
@@ -582,7 +582,7 @@ errlHndl_t tpmLogConfigEntries(TRUSTEDBOOT::TpmTarget & io_target)
// HW Key Hash
sha2_hash_t l_hw_key_hash;
- SECUREBOOT::getHwHashKeys(l_hw_key_hash);
+ SECUREBOOT::getHwKeyHash(l_hw_key_hash);
l_err = pcrExtend(PCR_1, l_hw_key_hash,
sizeof(sha2_hash_t),"HW KEY HASH");
if (l_err)
diff --git a/src/usr/secureboot/trusted/trustedboot.H b/src/usr/secureboot/trusted/trustedboot.H
index 31dcfc2be..14cbe8b93 100644
--- a/src/usr/secureboot/trusted/trustedboot.H
+++ b/src/usr/secureboot/trusted/trustedboot.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,6 +55,8 @@ extern trace_desc_t* g_trac_trustedboot;
namespace TRUSTEDBOOT
{
+const size_t DEFAULT_BIN_TRACE_SIZE = 128;
+
/// Common static values
enum
{
OpenPOWER on IntegriCloud