summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2016-10-17 12:15:40 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-11-14 17:17:33 -0500
commit16263a641c48773091dd60b55e28ad77ca5a8574 (patch)
tree97120f76deb4132a1a1b7ceba8701318c5663a68 /src
parenta904e156364a8f0fd5f6bc2b7094f79cf77da1b2 (diff)
downloadblackbird-hostboot-16263a641c48773091dd60b55e28ad77ca5a8574.tar.gz
blackbird-hostboot-16263a641c48773091dd60b55e28ad77ca5a8574.zip
Secure PNOR Resource Provider port from p8
Adds a Secure PNOR Resource Provider (SPNORRP) layer on top of the original PNORRP to handle verification of secured PNOR sections. Change-Id: Iff25abf599f3c850197c6e6d23ff03e5edf945bb RTC:163078 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31588 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/pnor/pnor_const.H8
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H16
-rw-r--r--src/include/usr/pnor/pnorif.H43
-rw-r--r--src/include/usr/secureboot/containerheader.H242
-rw-r--r--src/include/usr/secureboot/header.H144
-rw-r--r--src/include/usr/secureboot/rom.H195
-rw-r--r--src/include/usr/secureboot/service.H31
-rw-r--r--src/include/usr/secureboot/trustedbootif.H28
-rw-r--r--src/include/usr/vmmconst.h18
-rw-r--r--src/usr/pnor/makefile1
-rw-r--r--src/usr/pnor/pnor_common.C13
-rw-r--r--src/usr/pnor/pnor_utils.C26
-rw-r--r--src/usr/pnor/pnor_utils.H9
-rw-r--r--src/usr/pnor/pnorrp.C271
-rw-r--r--src/usr/pnor/spnorrp.C948
-rw-r--r--src/usr/pnor/spnorrp.H190
-rw-r--r--src/usr/pnor/test/pnorrptest.H8
-rw-r--r--src/usr/secureboot/base/containerheader.C248
-rw-r--r--src/usr/secureboot/base/header.C33
-rw-r--r--src/usr/secureboot/base/makefile5
-rw-r--r--src/usr/secureboot/base/securerom.C19
-rw-r--r--src/usr/secureboot/base/securerom.H10
-rw-r--r--src/usr/secureboot/base/service.C110
-rw-r--r--src/usr/secureboot/base/test/secureromtest.H3
-rw-r--r--src/usr/secureboot/header.H53
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C23
26 files changed, 2528 insertions, 167 deletions
diff --git a/src/include/usr/pnor/pnor_const.H b/src/include/usr/pnor/pnor_const.H
index 9b65876fd..ddc4d19d5 100644
--- a/src/include/usr/pnor/pnor_const.H
+++ b/src/include/usr/pnor/pnor_const.H
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <builtins.h>
+#include <config.h>
namespace PNOR
{
@@ -67,7 +68,6 @@ enum SectionId
RINGOVD, /**< Ring override data */
NUM_SECTIONS, /**< Number of defined sections */
-
FIRST_SECTION = TOC, /**< First section (for looping) */
/**< Used for error cases, initialization */
INVALID_SECTION = NUM_SECTIONS,
@@ -79,6 +79,7 @@ enum SectionId
// Size and layout of this structure must be maintained for debug framework.
struct SectionInfo_t
{
+ SectionInfo_t(): id(INVALID_SECTION) {}
SectionId id; /**< Identifier for this section */
const char* name; /**< Name of the section */
uint64_t vaddr; /**< Virtual address of the start of the section */
@@ -88,6 +89,11 @@ struct SectionInfo_t
bool sha512Version; /**< Version Checking */
bool sha512perEC; /**< Version Checking perEC */
bool readOnly; /**< Section is read only */
+#ifdef CONFIG_SECUREBOOT
+ size_t secureProtectedPayloadSize; /**< Cache the secure payload size so
+ that the secure container only
+ needs to be parsed once */
+#endif
};
/**
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index 4235339bd..b7fd96bee 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -96,6 +96,18 @@ namespace PNOR
// pnor_common.C
MOD_PNORCOMMON_PARSETOC = 0xC0, /**< PNOR::parseTOC */
+
+ // spnorrp.C
+ // Note: 0xD0 is available, so should be the next one used for spnorrp.
+ // Remove this comment after doing so.
+ MOD_SPNORRP_DIDSTARTUPFAIL = 0xD1, /**< didSecureStartupFail(rc) */
+ MOD_SPNORRP_ALLOCATE_BLOCK = 0xD2, /**< SPnorRP::initDaemon */
+ MOD_SPNORRP_WAITFORMESSAGE = 0xD3, /**< SPnorRP::waitForMessage */
+ MOD_SPNORRP_VERIFYSECTIONS = 0xD4, /**< SPnorRP::verifySections */
+ MOD_SPNORRP_SET_PERMISSION = 0xD5, /**< SPnorRP::initDaemon */
+ MOD_PNORRP_LOADSECURESECTION = 0xD6, /**< PnorRP::loadSecureSection */
+ MOD_SPNORRP_BASE_EXT_VER_CHK = 0xD7, /**< SPnorRP::baseExtVersCheck */
+ MOD_SPNORRP_KEY_TRAN_CHK = 0xD8, /**< SPnorRP::keyTransitionCheck */
};
enum PNORReasonCode
@@ -157,6 +169,10 @@ namespace PNOR
RC_TOC_HDR_CHECKSUM_ERR = PNOR_COMP_ID | 0x2C,
RC_PNOR_PARSE_ENTRIES_ERR = PNOR_COMP_ID | 0x2D,
RC_PNOR_SET_VADDR_FAILED = PNOR_COMP_ID | 0x2E,
+ RC_BASE_EXT_MISMATCH = PNOR_COMP_ID | 0x2F,
+ RC_KEY_TRAN_FLAG_UNSET = PNOR_COMP_ID | 0x30,
+ RC_BAD_SECURE_MAGIC_NUM = PNOR_COMP_ID | 0x31,
+
//@fixme-RTC:131607-Temporary value to allow HWSV compile
//termination_rc
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index f5e4fc385..311c6c4b4 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -81,6 +81,7 @@ errlHndl_t getSideInfo (SideId i_side, SideInfo_t& o_info);
errlHndl_t getSectionInfo( SectionId i_section,
SectionInfo_t& o_info );
+#ifdef CONFIG_SECUREBOOT
/**
* @brief Loads requested PNOR section to secure virtual address space
*
@@ -112,6 +113,48 @@ errlHndl_t loadSecureSection(SectionId i_section);
errlHndl_t unloadSecureSection(SectionId i_section);
/**
+ * @brief Memcmp a vaddr to the known secureboot magic number
+ *
+ * @param[in] i_vaddr: vaddr of secureboot header to check for magic number
+ * Note: must point to a buffer of size >= 4 bytes
+ *
+ * @return bool - True if the magic number and starting bytes of the vaddr
+ * match. False otherwise.
+ */
+bool cmpSecurebootMagicNumber(const uint8_t* i_vaddr);
+
+/**
+ * @brief Returns true if a PNOR section has the secureboot container
+ * header magic number at the beginning. This is mainly used to
+ * ignore unwanted PNOR sections like secureboot key transition.
+ * It indicates the section has valid content to be securely
+ * loaded, otherwise the section content will not be loaded.
+ * If a section does not have the header but needs to be loaded,
+ * it will fail ROM verify later on anyhow.
+ * Note: Does not work with HBB section and will assert if attempted
+ *
+ * @param[in] i_section: PNOR section to check first bytes of.
+ * @param[out] o_valid: true if section has the correct magic number at
+ * the beginning
+ *
+ * @return errlHndl_t - NULL if success, errlHndl_t otherwise.
+ * */
+errlHndl_t hasSecurebootMagicNumber(SectionId i_section, bool &o_valid);
+#endif // CONFIG_SECUREBOOT
+
+
+/**
+ * @brief Determines whether the given section is inhibited by secure boot
+ * for containing attribute overrides.
+ *
+ * @param[in] i_section PNOR section to test.
+ *
+ * @return bool True if inhibited section, false otherwise.
+ */
+bool isInhibitedSection(const uint32_t i_section);
+
+
+/**
* @brief Write the data back from hostboot memory to PNOR of a given section
* of PNOR
*
diff --git a/src/include/usr/secureboot/containerheader.H b/src/include/usr/secureboot/containerheader.H
new file mode 100644
index 000000000..c5188e629
--- /dev/null
+++ b/src/include/usr/secureboot/containerheader.H
@@ -0,0 +1,242 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/containerheader.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] 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 __SECUREBOOT_CONTAINER_HEADER_H
+#define __SECUREBOOT_CONTAINER_HEADER_H
+
+#include <errl/errlentry.H>
+#include <secureboot/service.H>
+#include <secureboot/rom.H>
+
+// Forward Declaration
+class SecureROMTest;
+
+namespace SECUREBOOT
+{
+
+/** @class ContainerHeader
+ * @brief Class for parsing secureboot container headers.
+ */
+class ContainerHeader
+{
+ public:
+
+ /**
+ * @brief ContainerHeader
+ *
+ * This constructor parses the input container header and sets values
+ * accordingly so they can be retrieved later.
+ *
+ * @param[in] i_header Secure container header to parse.
+ * NULL input will assert
+ */
+ ContainerHeader(const void* i_header):
+ iv_isValid(false),iv_hdrBytesRead(0)
+ {
+ assert(i_header != NULL);
+ iv_pHdrStart = reinterpret_cast<const uint8_t*>(i_header);
+ memset(&iv_headerInfo, 0x00, sizeof(iv_headerInfo));
+ memset(iv_hwKeyHash, 0, sizeof(SHA512_t));
+ parse_header(i_header);
+ };
+
+ /**
+ * @brief Destructor
+ */
+ ~ContainerHeader(){};
+
+ /**
+ * @brief Retrieves total container size (includes header, payload text,
+ * and payload data sizes)
+ * @return size_t - Total container size in bytes
+ */
+ size_t totalContainerSize() const;
+
+ /**
+ * @brief Retrieves pointer to first hw key
+ * @return ecc_key_t* - ptr to first hw key
+ */
+ const ecc_key_t* hw_keys() const;
+
+ /**
+ * @brief Total size of all hw keys concatenated
+ */
+ static const size_t totalHwKeysSize = HW_KEY_COUNT*sizeof(ecc_key_t);
+
+ /**
+ * @brief Retrieves payload text size
+ * @return size_t - size of payload text size
+ */
+ size_t payloadTextSize() const;
+
+ /**
+ * @brief Retrieves payload text hash
+ * @return SHA512_t* - ptr to hash of payload text
+ */
+ const SHA512_t* payloadTextHash() const;
+
+ /**
+ * @brief Retrieves total size of all sw keys concatenated
+ * @return size_t - size of concatenated sw keys
+ */
+ size_t totalSwKeysSize() const;
+
+ /**
+ * @brief Retrieves sw public key hash
+ * @return SHA512_t* - ptr to hash of sw public keys
+ */
+ const SHA512_t* swKeyHash() const;
+
+ /**
+ * @brief Retrieves pointer to first sw key
+ * @return ecc_key_t* - ptr to first sw key
+ */
+ const ecc_key_t* sw_keys() const;
+
+ /**
+ * @brief Retrieves pointer to first sw signature
+ * @return ecc_key_t* - ptr to first sw signature
+ */
+ const ecc_key_t* sw_sigs() const;
+
+ /**
+ * @brief Retrieves pointer to sb flag struct holding all hw and sw
+ * flags set when parsing the header.
+ * @return sb_flags_t - hw and sw flag struct
+ */
+ const sb_flags_t* sb_flags() const;
+
+ /**
+ * @brief Retrieves hw public key hash
+ * @return SHA512_t* - ptr to hash of hw public keys
+ */
+ const SHA512_t* hwKeyHash() const;
+
+ /**
+ * @brief Returns if the parsed header is a valid secureboot one. This
+ * is a temporary, non-secure way of pragmatically determining
+ * if secureboot signing was supported. Eventually it will always
+ * happen
+ * @return bool - whether or not the container is a valid secureboot
+ */
+ bool isValid() const;
+
+ private:
+ /**
+ * @brief Default Constructor in private to prevent being instantiated
+ * by non friend/children derivatives.
+ */
+ ContainerHeader(){};
+
+ /**
+ * @brief Complete container header structure based on ROM structures
+ */
+ struct SecureHeaderInfo
+ {
+ ROM_container_raw hw_hdr;
+ ROM_prefix_header_raw hw_prefix_hdr;
+ ROM_prefix_data_raw hw_prefix_data;
+ ROM_sw_header_raw sw_hdr;
+ ROM_sw_sig_raw sw_sig;
+ };
+
+ // Entire cached container header content
+ SecureHeaderInfo iv_headerInfo;
+
+ // Indicates if container header is a valid, in a very loose sense,
+ // secureboot header.
+ bool iv_isValid;
+
+ // Pointer to the start of the container header
+ const uint8_t* iv_pHdrStart;
+
+ // Counter for bytes read while parsing the container header
+ size_t iv_hdrBytesRead;
+
+ // Total size of all software keys concatenated
+ size_t iv_totalSwKeysSize;
+
+ // Struct to hold all hw and sw flags set
+ sb_flags_t iv_sbFlags;
+
+ // HW keys' hash for current container.
+ SHA512_t iv_hwKeyHash;
+
+ /**
+ * @brief Determines what flags are set based on the hw and sw flag bit
+ * fields in the container header.
+ * Also sets iv_sbFlags private member
+ */
+ void parseFlags();
+
+ /**
+ * @brief Generate and store hw key hash. Concatenate all hw public keys
+ * and then take sha512 hash.
+ * Also sets iv_hwKeyHash private member
+ */
+ void genHwKeyHash();
+
+ /**
+ * @brief Weak check to determine if secureboot header looks right.
+ * Also sets iv_isValid private member
+ */
+ void validate();
+
+ /**
+ * @brief Print out useful sections of the container header
+ */
+ void print() const;
+
+ /**
+ * @brief parse_header Blob
+ *
+ * Parses a secure container header defined by ROM structures and set
+ * internal header structure.
+ *
+ * @param[in] i_containerHdr Secure container header to parse
+ * NULL input will assert
+ */
+ void parse_header(const void* i_header);
+
+ /**
+ * @brief Checks bounds of parsing before mempy and increments pointer
+ *
+ * Ensures that we don't memcpy more bytes than the max size of a
+ * secure container header. Asserts on out of bounds memcpy.
+ *
+ * @param[in] i_dest Pointer to the memory location to copy to
+ * NULL input will assert
+ * @param[in] io_hdr Pointer to current location of container header
+ * NULL input will assert
+ * @param[in] i_size Number of bytes to copy
+ */
+ void safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
+ const size_t i_size);
+
+ friend class ::SecureROMTest;
+};
+
+}; //end of SECUREBOOT namespace
+
+#endif
diff --git a/src/include/usr/secureboot/header.H b/src/include/usr/secureboot/header.H
new file mode 100644
index 000000000..f7a5121c6
--- /dev/null
+++ b/src/include/usr/secureboot/header.H
@@ -0,0 +1,144 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/header.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* [+] 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 __SECUREBOOT_HEADER_H
+#define __SECUREBOOT_HEADER_H
+
+#include <stdint.h>
+#include <pnor/pnorif.H>
+#include <util/singleton.H>
+
+/** @file header.H
+ *
+ * @brief Class for manipulating the base image (HBB) secureboot header.
+ */
+namespace SECUREBOOT
+{
+ /** @class Header
+ * @brief Class for storing the base image (HBB) header for later use.
+ */
+ class Header
+ {
+ public:
+ /**
+ * @brief Build a base image (HBB) header object
+ */
+ Header()
+ : iv_data(NULL)
+ {
+ }
+
+ /**
+ * @brief Destroy a base image (HBB) header object, including any
+ * cached header page
+ */
+ ~Header()
+ {
+ free(iv_data);
+ 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();
+
+ /**
+ * @brief Extracts base image (HBB) header (ECC removed) from
+ * HBB secure load address (HRMOR - 4k) to support extending
+ * HBB measurements to TPM in secure mode.
+ *
+ * @warning Asserts if header is already cached (code bug)
+ */
+ void loadSecurely();
+
+ /**
+ * @brief Caches non-secure PNOR copy of the base image (HBB)
+ * header (ECC removed) to support extending HBB measurements
+ * to TPM in non-secure mode.
+ *
+ * @param[in] i_pHeader Pointer to non-secure 4k HBB header
+ * extracted from PNOR.
+ *
+ * @warning Asserts if input pointer is NULL (code bug)
+ * @warning Asserts if header already cached (code bug)
+ * @warning Memory violation if buffer data is less than 4k in size
+ * (code bug)
+ * @warning Ignores buffer data beyond 4k in size
+ */
+ void setNonSecurely(
+ const void* i_pHeader);
+
+ /**
+ * @brief Return pointer to base image (HBB) header.
+ *
+ * @par Detailed Description:
+ * When SBE first loads Hostboot, if system is in secure mode,
+ * it copies the HBB code to the HRMOR address (aka the secure
+ * load address) and puts the HBB header 4k in front of it. In
+ * non-secure mode, SBE only loads the HBB code to the HRMOR and
+ * discards the header, leaving no trace of it in memory. When
+ * HBB gets control, if in secure mode, it copies its own header
+ * from HRMOR-4k and caches it in this object. Otherwise, if
+ * not in secure mode, it pulls the header from PNOR and writes
+ * it into this object. This API then returns the addresses of
+ * the cached header.
+ *
+ * @param[out] o_pHeader Pointer to HBB header
+ *
+ * @warning Asserts if HBB header not loaded (code bug)
+ */
+ void getHeader(
+ const void*& o_pHeader) const;
+
+ private:
+
+ /**
+ * @brief Returns base (HBB) image secure load address (the address
+ * where SBE -always- loads hostboot regardless of security
+ * state)
+ *
+ * @param[out] o_pCode Base (HBB) image secure load address
+ */
+ void _calcSecureLoadAddr(
+ const void*& o_pCode) const;
+
+ // Pointer to copy of the base image's (HBB's) secureboot header
+ void* iv_data;
+
+ // Don't allow copies / assignments
+ Header(const Header& that);
+ Header& operator=(const Header&);
+ };
+
+ /**
+ * @brief Returns the base image (HBB) header singleton
+ *
+ * @return Header Reference to base image (HBB) header object
+ */
+ Header& baseHeader();
+
+};
+
+#endif
diff --git a/src/include/usr/secureboot/rom.H b/src/include/usr/secureboot/rom.H
new file mode 100644
index 000000000..45f9c5dd4
--- /dev/null
+++ b/src/include/usr/secureboot/rom.H
@@ -0,0 +1,195 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/secureboot/rom.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] 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 __SECUREBOOT_ROM_H
+#define __SECUREBOOT_ROM_H
+
+// Consts used for container header validation
+const uint32_t MAGIC_NUMBER = 0x17082011;
+const uint16_t ROM_VERSION = 1;
+const uint8_t ROM_HASH_ALG = 1;
+const uint8_t ROM_SIG_ALG = 1;
+const uint8_t HW_KEY_COUNT = 3;
+const uint8_t SW_KEY_COUNT_MIN = 1;
+const uint8_t SW_KEY_COUNT_MAX = 3;
+const size_t MAX_SECURE_HEADER_SIZE = 4096;
+
+// Security Flags
+
+// HW Security Flags
+enum HW_SB_FLAGS
+{
+ HB_FW_FLAG = 0x80000000,
+ OPAL_FLAG = 0x40000000,
+ PHYP_FLAG = 0x20000000,
+ KEY_TRANSITION_FLAG = 0x00000001
+};
+
+// SW Security Flags
+enum SW_SB_FLAGS
+{
+ // placeholder
+};
+
+// Structure to store all hw and sw flag values in a container header
+struct sb_flags_t
+{
+ sb_flags_t() : hw_hb_fw(false), hw_opal(false), hw_phyp(false),
+ hw_key_transition(false) {}
+ bool hw_hb_fw;
+ bool hw_opal;
+ bool hw_phyp;
+ bool hw_key_transition;
+};
+
+/******************************************************************/
+/* Start of Chip Logic Secure ROM include section */
+/******************************************************************/
+// These defines come from the following directory:
+// /afs/awd/projects/eclipz/c22/libs/tp/logic/p8m/head/trusted_boot_rom/src
+
+/* From hw_utils.h: */
+#define ECID_SIZE 16
+#define PIBMEM 0x00080000
+#define PIBMEM_HW_KEY_HASH (PIBMEM +0x0008)
+
+/* From ecverify.h */
+#define EC_COORDBYTES 66 /* P-521 */
+typedef uint8_t ecc_key_t[2*EC_COORDBYTES];
+typedef uint8_t ecc_signature_t[2*EC_COORDBYTES];
+
+/* From sha512.h: */
+#define SHA512_DIGEST_LENGTH 64
+typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ \
+ SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
+
+typedef uint8_t sha2_byte; /* Exactly 1 byte */
+
+/* From ROM.h */
+typedef enum { ROM_DONE, ROM_FAILED, PHYP_PARTIAL } ROM_response;
+
+/* From ROM.h */
+typedef struct {
+ uint16_t version; // (1: see versions above)
+ uint8_t hash_alg; // (1: SHA-512)
+ uint8_t sig_alg; // (1: SHA-512/ECDSA-521)
+}__attribute__((packed)) ROM_version_raw;
+
+typedef struct {
+ uint32_t magic_number; // (17082011)
+ uint16_t version; // (1: see versions above)
+ uint64_t container_size; // filled by caller
+ uint64_t target_hrmor; // filled by caller
+ uint64_t stack_pointer; // filled by caller
+ //bottom of stack -> 128k added by rom code to get real stack pointer
+ ecc_key_t hw_pkey_a;
+ ecc_key_t hw_pkey_b;
+ ecc_key_t hw_pkey_c;
+ uint64_t prefix; // prefix header place holder
+ // followed by sw header (if not special prefix)
+ // followed by optional unprotected payload data
+}__attribute__((packed)) ROM_container_raw;
+
+typedef struct {
+ ROM_version_raw ver_alg;
+ uint64_t code_start_offset;
+ uint64_t reserved;
+ uint32_t flags;
+ uint8_t sw_key_count;
+ uint64_t payload_size;
+ sha2_hash_t payload_hash;
+ uint8_t ecid_count;
+ uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
+ // followed by prefix data (sig,keys) key raw
+}__attribute__((packed)) ROM_prefix_header_raw;
+
+#define PREFIX_HEADER_SIZE(_p) (sizeof(ROM_prefix_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
+
+typedef struct {
+ ecc_signature_t hw_sig_a;
+ ecc_signature_t hw_sig_b;
+ ecc_signature_t hw_sig_c;
+ ecc_key_t sw_pkey_p;
+ ecc_key_t sw_pkey_q;
+ ecc_key_t sw_pkey_r;
+}__attribute__((packed)) ROM_prefix_data_raw;
+
+typedef struct {
+ ROM_version_raw ver_alg;
+ uint64_t code_start_offset;
+ uint64_t reserved;
+ uint32_t flags;
+ uint8_t reserved_0;
+ uint64_t payload_size;
+ sha2_hash_t payload_hash;
+ uint8_t ecid_count;
+ uint8_t ecid[ECID_SIZE]; // optional ecid place holder ecid_count * ecid_size(128 bits)
+ // followed by sw sig raw
+}__attribute__((packed)) ROM_sw_header_raw;
+
+#define SW_HEADER_SIZE(_p) (sizeof(ROM_sw_header_raw)+((_p->ecid_count-1)*ECID_SIZE))
+
+typedef struct {
+ ecc_signature_t sw_sig_p;
+ ecc_signature_t sw_sig_q;
+ ecc_signature_t sw_sig_r;
+ // followed by zero's padding to 4K
+ // followed by protected sw payload_data
+ // followed by unprotected sw payload_text
+}__attribute__((packed)) ROM_sw_sig_raw;
+
+typedef struct {
+ sha2_hash_t hw_key_hash;
+ uint8_t my_ecid[ECID_SIZE];
+ uint64_t entry_point;
+ uint64_t log;
+}__attribute__((packed)) ROM_hw_params;
+
+// Need this for the following definition
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// Interfaces for Assembly Functions to call into Secure ROM
+// - 1st parameter is address of function offset into Secure ROM,
+// followed by additional parameters as necssary
+
+ROM_response call_rom_verify(void*, ROM_container_raw*, ROM_hw_params*);
+void call_rom_SHA512(void*, const sha2_byte *, size_t, sha2_hash_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Offsets needed to call functions in jump table at start of */
+/* SecureROM code - see .../trusted_boot_rom/bootrom.dis */
+#define SHA512_HASH_FUNCTION_OFFSET 0x20
+#define ROM_VERIFY_FUNCTION_OFFSET 0x30
+
+/******************************************************************/
+/* End of Chip Logic ROM include section */
+/******************************************************************/
+
+#endif
diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H
index 1cc518007..577b27284 100644
--- a/src/include/usr/secureboot/service.H
+++ b/src/include/usr/secureboot/service.H
@@ -33,8 +33,22 @@ typedef uint8_t SHA512_t[64];
typedef uint8_t __attribute__((aligned(8))) sha2_hash_t[ \
SHA512_DIGEST_LENGTH / sizeof(uint8_t) ];
+// TODO securebootp9 added for spnorrp.C - service.H needs many more updates
+// in order to match the p8 version
+const size_t HASH_PAGE_TABLE_ENTRY_SIZE = 32;
+typedef uint8_t PAGE_TABLE_ENTRY_t[HASH_PAGE_TABLE_ENTRY_SIZE];
+
+
namespace SECUREBOOT
{
+ // TODO securebootp9 - the two constants below were taken from master-p8
+ // branch (version 2257b1) of service.H underneath secureboot.
+ // The p9 version of service.H needs many more updates in order to match
+ // the p8 version.
+ const uint64_t PROC_SECURITY_SWITCH_REGISTER = 0x00010005ull;
+ const uint64_t
+ PROC_SECURITY_SWITCH_TRUSTED_BOOT_MASK = 0x8000000000000000ull;
+
/** @brief Perform initialization of Secureboot for the Base image.
*
* - Copy secure header from original location.
@@ -60,11 +74,13 @@ namespace SECUREBOOT
* @brief Verify Signed Container
*
* @param[in] i_container Void pointer to effective address of container
- * @param[in] i_size Size of container in bytes
+ * @param[in] i_hwKeyHash Custom hw keys' hash to test against
+ * [default = nullptr, use current hw hash key]
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t verifyContainer(void * i_container, size_t i_size);
+ errlHndl_t verifyContainer(void * i_container,
+ const sha2_hash_t* i_hwKeyHash = nullptr);
/**
* @brief Hash Signed Blob
@@ -75,7 +91,7 @@ namespace SECUREBOOT
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t hashBlob(void * i_blob, size_t i_size, SHA512_t o_buf);
+ 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
@@ -84,6 +100,15 @@ namespace SECUREBOOT
* hash to.
*/
void getHwHashKeys(sha2_hash_t o_hash);
+
+ /**
+ * @brief Common secureboot handler for secureboot failures.
+ * Properly handles callouts etc.
+ *
+ * @return i_err - Error log to cascade through failure path.
+ */
+ void handleSecurebootFailure(errlHndl_t &i_err);
+
}
#endif
diff --git a/src/include/usr/secureboot/trustedbootif.H b/src/include/usr/secureboot/trustedbootif.H
index ae6d183af..eaef78a74 100644
--- a/src/include/usr/secureboot/trustedbootif.H
+++ b/src/include/usr/secureboot/trustedbootif.H
@@ -37,6 +37,8 @@
#include <i2c/tpmddif.H>
#include <errl/errlentry.H>
#include <list>
+#include <pnor/pnorif.H>
+#include <secureboot/containerheader.H>
namespace TRUSTEDBOOT
{
@@ -160,6 +162,32 @@ namespace TRUSTEDBOOT
*/
bool enabled();
+ /**
+ * @brief Wrapper around pcrExtend for measuring PNOR sections
+ * @param[in] i_conHdr Reference to ContainerHeader of a section
+ * @param[in] i_vaddr Pointer to a virtual address for the protected
+ * portion of the PNOR section.
+ * [Not used if SECUREBOOT::enabled()]
+ * @param[in] i_sec Section ID of PNOR section
+ * @return errlHndl_t NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t extendPnorSectionHash(const SECUREBOOT::ContainerHeader& i_conHdr,
+ const void* i_vaddr,
+ const PNOR::SectionId i_sec);
+
+ /**
+ *
+ * @brief Extends the Hostboot base image to the TPM
+ *
+ * @warning No-op if trusted boot compiled out
+ *
+ * @return errHndl_t Error log pointer
+ * @retval NULL Successfully extended Hostboot base image to the TPM
+ * @retval !NULL Failed to extend Hostboot base image to TPM
+ * */
+ errlHndl_t extendBaseImage();
+
} // end TRUSTEDBOOT namespace
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index 676e54f5a..1c91ae326 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -87,6 +87,17 @@
/** PNOR Resource Provider is at 2GB */
#define VMM_VADDR_PNOR_RP (2 * GIGABYTE)
+/** Temp PNOR Resource Provider space is at 5GB */
+#define VMM_VADDR_SPNOR_TEMP (5 * GIGABYTE)
+
+/** The delta between PNOR RP and temp space and
+ * the delta between temp space and Secure PNOR RP space is 3GB
+ */
+#define VMM_VADDR_SPNOR_DELTA (VMM_VADDR_SPNOR_TEMP - VMM_VADDR_PNOR_RP)
+
+/** Secure PNOR Resource Provider is at 8GB */
+#define VMM_VADDR_SPNOR_RP (VMM_VADDR_SPNOR_TEMP + VMM_VADDR_SPNOR_DELTA)
+
/** SBE Update process is at 3GB, uses 512KB */
#define VMM_VADDR_SBE_UPDATE (3 * GIGABYTE)
#define VMM_SBE_UPDATE_SIZE (512 * KILOBYTE)
@@ -104,9 +115,10 @@
/** Virtual memory block priorities */
enum BlockPriority
{
- PNOR_PRIORITY = 0, //No dependencies
- VFS_PRIORITY = (PNOR_PRIORITY + 1), //Dependent on PNOR
- ATTR_PRIORITY = (PNOR_PRIORITY + 1), //Dependent on PNOR
+ PNOR_PRIORITY = 0, //No dependencies
+ SPNOR_PRIORITY = (PNOR_PRIORITY + 1), //Dependent on PNOR
+ VFS_PRIORITY = (SPNOR_PRIORITY + 1), //Dependent on PNOR and SPNOR
+ ATTR_PRIORITY = (SPNOR_PRIORITY + 1), //Dependent on PNOR and SPNOR
};
/**
diff --git a/src/usr/pnor/makefile b/src/usr/pnor/makefile
index c1ebe38f0..b2c261a4b 100644
--- a/src/usr/pnor/makefile
+++ b/src/usr/pnor/makefile
@@ -29,6 +29,7 @@ ROOTPATH = ../../..
MODULE = pnor
OBJS += pnor_utils.o
OBJS += pnorrp.o
+OBJS += $(if $(CONFIG_SECUREBOOT),spnorrp.o)
OBJS += pnordd.o
OBJS += pnor_common.o
OBJS += pnorvalid.o
diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C
index c1ceab291..351386256 100644
--- a/src/usr/pnor/pnor_common.C
+++ b/src/usr/pnor/pnor_common.C
@@ -367,3 +367,16 @@ errlHndl_t PNOR::extendHash(uint64_t i_addr, size_t i_size, const char* i_name)
return l_errhdl;
}
+bool PNOR::isInhibitedSection(const uint32_t i_section)
+{
+// TODO securebootp9 for now we won't be inhibiting overrides
+#ifdef CONFIG_SECUREBOOT
+// return (i_section == ATTR_PERM ||
+// i_section == ATTR_TMP) &&
+// SECUREBOOT::enabled();
+ return false;
+#else
+ return false;
+#endif
+}
+
diff --git a/src/usr/pnor/pnor_utils.C b/src/usr/pnor/pnor_utils.C
index e522ea942..ee3355347 100644
--- a/src/usr/pnor/pnor_utils.C
+++ b/src/usr/pnor/pnor_utils.C
@@ -337,8 +337,8 @@ void PNOR::parseEntries (ffs_hdr* i_ffs_hdr,
((io_TOC[secId].size * 8 ) / 9);
}
- // TODO RTC:96009 handle version header w/secureboot
- if (io_TOC[secId].version == FFS_VERS_SHA512)
+ if (io_TOC[secId].version == FFS_VERS_SHA512
+ && !PNOR::isSecureSection(secId))
{
//increment flash addr for sha header
if (io_TOC[secId].integrity == FFS_INTEG_ECC_PROTECT)
@@ -349,11 +349,31 @@ void PNOR::parseEntries (ffs_hdr* i_ffs_hdr,
{
io_TOC[secId].flashAddr += PAGESIZE ;
}
+
+ // now that we've skipped the header
+ // adjust the size to reflect that
io_TOC[secId].size -= PAGESIZE;
}
} // For TOC Entries
}
-
+bool PNOR::isSecureSection(const uint32_t i_section)
+{
+// TODO securebootp9 uncomment these sections as they become ready for
+// inclusion in p9. Remove this comment after the last one.
+#ifdef CONFIG_SECUREBOOT
+// return i_section == HB_EXT_CODE ||
+// i_section == HB_DATA ||
+// i_section == SBE_IPL ||
+// i_section == CENTAUR_SBE ||
+// i_section == PAYLOAD ||
+// i_section == SBKT ||
+// i_section == OCC ||
+// i_section == HB_RUNTIME;
+ return false;
+#else
+ return false;
+#endif
+}
diff --git a/src/usr/pnor/pnor_utils.H b/src/usr/pnor/pnor_utils.H
index ed0f7176b..75d85d77b 100644
--- a/src/usr/pnor/pnor_utils.H
+++ b/src/usr/pnor/pnor_utils.H
@@ -220,6 +220,15 @@ void parseEntries (ffs_hdr* i_ffs_hdr,
SectionData_t* io_TOC,
ffs_entry*& o_err_entry);
+/**
+ * @brief Determines whether the given section is secured by secure boot
+ *
+ * @param[in] i_section PNOR section to test.
+ *
+ * @return bool True if secure section, false otherwise.
+ */
+bool isSecureSection(const uint32_t i_section);
+
} // End namespace PNOR
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index 0c1feea77..ab7c66f23 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -24,6 +24,7 @@
/* */
/* IBM_PROLOG_END_TAG */
#include "pnorrp.H"
+#include "spnorrp.H"
#include <pnor/pnor_reasoncodes.H>
#include <initservice/taskargs.H>
#include <sys/msg.h>
@@ -44,10 +45,19 @@
#include <endian.h>
#include <util/align.H>
#include <config.h>
+#include <pnor/pnorif.H>
#include "pnor_common.H"
#include <hwas/common/hwasCallout.H>
#include <console/consoleif.H>
+#ifdef CONFIG_SECUREBOOT
+#include <secureboot/service.H>
+#include <secureboot/containerheader.H>
+//#include <secureboot/settings.H> TODO securebootp9 include settings.H
+#include <secureboot/header.H>
+#include <secureboot/trustedbootif.H>
+#endif
+
extern trace_desc_t* g_trac_pnor;
// Easy macro replace for unit testing
@@ -90,29 +100,6 @@ errlHndl_t PNOR::getSectionInfo( PNOR::SectionId i_section,
}
/**
- * @brief Loads requested PNOR section to secure virtual address space
- */
-errlHndl_t PNOR::loadSecureSection(const SectionId i_section)
-{
- //@TODO RTC 156118
- // Replace with call to secure provider to load the section
- errlHndl_t pError=NULL;
- return pError;
-}
-
-/**
- * @brief Flushes any applicable pending writes and unloads requested PNOR
- * section from secure virtual address space
- */
-errlHndl_t PNOR::unloadSecureSection(const SectionId i_section)
-{
- //@TODO RTC 156118
- // Replace with call to secure provider to load the section
- errlHndl_t pError=NULL;
- return pError;
-}
-
-/**
* @brief Clear pnor section
*/
errlHndl_t PNOR::clearSection(PNOR::SectionId i_section)
@@ -175,16 +162,21 @@ void PnorRP::init( errlHndl_t &io_rtaskRetErrl )
{
TRACUCOMP(g_trac_pnor, "PnorRP::init> " );
uint64_t rc = 0;
+ uint64_t rcs = 0; // spnorrp return code
errlHndl_t l_errl = NULL;
- if( Singleton<PnorRP>::instance().didStartupFail(rc) )
+ if( Singleton<PnorRP>::instance().didStartupFail(rc)
+#ifdef CONFIG_SECUREBOOT
+ || Singleton<SPnorRP>::instance().didStartupFail(rcs)
+#endif
+ )
{
/*@
* @errortype ERRL_SEV_CRITICAL_SYS_TERM
* @moduleid PNOR::MOD_PNORRP_DIDSTARTUPFAIL
* @reasoncode PNOR::RC_BAD_STARTUP_RC
- * @userdata1 return code
- * @userdata2 0
+ * @userdata1 return code pnorrp
+ * @userdata2 return code spnorrp
*
* @devdesc PNOR startup task returned an error.
* @custdesc A problem occurred while accessing the boot flash.
@@ -194,11 +186,22 @@ void PnorRP::init( errlHndl_t &io_rtaskRetErrl )
PNOR::MOD_PNORRP_DIDSTARTUPFAIL,
PNOR::RC_BAD_STARTUP_RC,
rc,
- 0,
+ rcs,
true /*Add HB SW Callout*/ );
l_errl->collectTrace(PNOR_COMP_NAME);
}
+ else
+ {
+ // 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
+ // Extend the base image to the TPM, regardless of how it was obtained
+ l_errl = TRUSTEDBOOT::extendBaseImage();
+ #endif
+ #endif
+ }
io_rtaskRetErrl=l_errl;
}
@@ -326,6 +329,53 @@ void PnorRP::initDaemon()
break;
}
+ #ifndef __HOSTBOOT_RUNTIME
+ #ifdef CONFIG_SECUREBOOT
+ 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
+ PNOR::SideInfo_t pnorInfo = {PNOR::WORKING};
+ l_errhdl = PnorRP::getSideInfo(PNOR::WORKING, pnorInfo);
+ if(l_errhdl != NULL)
+ {
+ break;
+ }
+
+ const SectionData_t* pHbb = &iv_TOC[PNOR::HB_BASE_CODE];
+ 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(
+ pnorInfo.hbbAddress,
+ pHbb->chip,
+ ecc,
+ pHeader,
+ fatalError);
+
+ // 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)
+ {
+ break;
+ }
+
+ // Skip the SBE header on the HBB image to get the real header
+ (void)SECUREBOOT::baseHeader().setNonSecurely(
+ pHeader);
+ }
+ #endif
+ #endif
+
// start task to wait on the queue
task_create( wait_for_message, NULL );
} while(0);
@@ -418,25 +468,49 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
break;
}
+ // inhibit any attempt to getSectionInfo on any attribute override
+ // sections if secureboot is enabled
+ bool l_inhibited = isInhibitedSection(id);
+
// Zero-length means the section is invalid
- if( 0 == iv_TOC[id].size )
+ if( 0 == iv_TOC[id].size
+ // attribute overrides inhibited by secure boot
+ || l_inhibited
+ )
{
TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> Invalid Section Requested : i_section=%d", i_section );
- TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }", iv_TOC[i_section].id, iv_TOC[i_section].size );
+ #ifdef CONFIG_SECUREBOOT
+ if (l_inhibited)
+ {
+ TRACFCOMP( g_trac_pnor, "PnorRP::getSectionInfo> "
+ "attribute override inhibited by secureboot");
+ }
+ #endif
+ uint64_t size = iv_TOC[i_section].size;
+ TRACFCOMP(g_trac_pnor, "o_info={ id=%d, size=%d }",
+ iv_TOC[i_section].id, size );
/*@
* @errortype
- * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO
- * @reasoncode PNOR::RC_INVALID_SECTION
- * @userdata1 Requested Section
- * @userdata2 TOC used
- * @devdesc PnorRP::getSectionInfo> Invalid Address for read/write
- * @custdesc A problem occurred while accessing the boot flash.
- */
+ * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO
+ * @reasoncode PNOR::RC_INVALID_SECTION
+ * @userdata1 Size of section
+ * @userdata2[0:7] TOC used
+ * @userdata2[8:15] Inhibited flag
+ * @userdata2[16:23] Requested Section
+ * @devdesc PnorRP::getSectionInfo> Invalid Address for
+ * read/write or prohibited by secureboot
+ * @custdesc A problem occurred while accessing the boot
+ * flash.
+ */
l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_GETSECTIONINFO,
PNOR::RC_INVALID_SECTION,
- TO_UINT64(i_section),
- iv_TOC_used,
+ size,
+ TO_UINT64(FOUR_UINT8_TO_UINT32(
+ iv_TOC_used,
+ l_inhibited,
+ i_section,
+ 0)),
true /*Add HB SW Callout*/);
l_errhdl->collectTrace(PNOR_COMP_NAME);
@@ -444,27 +518,108 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
id = PNOR::INVALID_SECTION;
break;
}
- } while(0);
- if (PNOR::INVALID_SECTION != id)
- {
- TRACDCOMP( g_trac_pnor, "PnorRP::getSectionInfo: i_section=%d, id=%d", i_section, iv_TOC[i_section].id );
-
- // copy my data into the external format
- o_info.id = iv_TOC[id].id;
- o_info.name = cv_EYECATCHER[id];
- o_info.vaddr = iv_TOC[id].virtAddr;
- o_info.flashAddr = iv_TOC[id].flashAddr;
- o_info.size = iv_TOC[id].size;
- o_info.eccProtected = ((iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT)
- != 0) ? true : false;
- o_info.sha512Version = ((iv_TOC[id].version & FFS_VERS_SHA512)
- != 0) ? true : false;
- o_info.sha512perEC = ((iv_TOC[id].version & FFS_VERS_SHA512_PER_EC)
- != 0) ? true : false;
- o_info.readOnly = ((iv_TOC[id].misc & FFS_MISC_READ_ONLY)
- != 0) ? true : false;
- }
+
+ if (PNOR::INVALID_SECTION != id)
+ {
+ TRACDCOMP( g_trac_pnor, "PnorRP::getSectionInfo: i_section=%d, id=%d", i_section, iv_TOC[i_section].id );
+
+ // copy my data into the external format
+ o_info.id = iv_TOC[id].id;
+ o_info.name = cv_EYECATCHER[id];
+
+#ifdef CONFIG_SECUREBOOT
+ o_info.secureProtectedPayloadSize = 0; // for non secure sections
+ // the protected payload size
+ // defaults to zero
+ // handle secure sections in SPnorRP's address space
+ if (PNOR::isSecureSection(o_info.id))
+ {
+ uint8_t* l_vaddr = reinterpret_cast<uint8_t*>(iv_TOC[id].virtAddr);
+ // By adding VMM_VADDR_SPNOR_DELTA twice we can translate a pnor
+ // address into a secure pnor address, since pnor, temp, and spnor
+ // spaces are equidistant.
+ // See comments in SPnorRP::verifySections() method in spnorrp.C
+ // and the definition of VMM_VADDR_SPNOR_DELTA in vmmconst.h
+ // for specifics.
+ o_info.vaddr = reinterpret_cast<uint64_t>(l_vaddr)
+ + VMM_VADDR_SPNOR_DELTA
+ + VMM_VADDR_SPNOR_DELTA;
+
+ // Get size of the secured payload for the secure section
+ // Note: the payloadSize we get back is untrusted because
+ // we are parsing the header in pnor (non secure space).
+ size_t payloadTextSize = 0;
+ // Do an existence check on the container to see if it's non-empty
+ // and has valid beginning bytes. For optional Secure PNOR sections.
+
+ if (PNOR::cmpSecurebootMagicNumber(l_vaddr))
+ {
+ SECUREBOOT::ContainerHeader l_conHdr(l_vaddr);
+ payloadTextSize = l_conHdr.payloadTextSize();
+ assert(payloadTextSize > 0,"Non-zero payload text size expected.");
+ }
+ else
+ {
+ uint32_t l_badMagicHeader = 0;
+ memcpy(&l_badMagicHeader, l_vaddr, sizeof(MAGIC_NUMBER));
+ TRACFCOMP( g_trac_pnor, ERR_MRK"PnorRP::getSectionInfo: magic number not valid to parse container for section = %s magic number = 0x%X",
+ o_info.name, l_badMagicHeader);
+ /*@
+ * @errortype
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO
+ * @reasoncode PNOR::RC_BAD_SECURE_MAGIC_NUM
+ * @userdata1 Requested Section
+ * @userdata2 Bad magic number
+ * @devdesc PNOR section does not have the known secureboot magic number
+ * @custdesc Corrupted flash image or firmware error during system boot
+ */
+ l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ PNOR::MOD_PNORRP_GETSECTIONINFO,
+ PNOR::RC_BAD_SECURE_MAGIC_NUM,
+ TO_UINT64(i_section),
+ TO_UINT64(l_badMagicHeader),
+ true /*Add HB SW Callout*/);
+ l_errhdl->collectTrace(PNOR_COMP_NAME);
+ break;
+ }
+ // skip secure header for secure sections at this point in time
+ o_info.vaddr += PAGESIZE;
+ // now that we've skipped the header we also need to adjust the
+ // size of the section to reflect that.
+ // Note: For unsecured sections, the header skip and size decrement
+ // was done previously in pnor_common.C
+ o_info.size -= PAGESIZE;
+
+ // cache the value in SectionInfo struct so that we can
+ // parse the container header less often
+ o_info.secureProtectedPayloadSize = payloadTextSize;
+ }
+ else
+#endif
+ {
+ o_info.vaddr = iv_TOC[id].virtAddr;
+ }
+
+ o_info.flashAddr = iv_TOC[id].flashAddr;
+ o_info.size = iv_TOC[id].size;
+ o_info.eccProtected = ((iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT)
+ != 0) ? true : false;
+ o_info.sha512Version = ((iv_TOC[id].version & FFS_VERS_SHA512)
+ != 0) ? true : false;
+ o_info.sha512perEC = ((iv_TOC[id].version & FFS_VERS_SHA512_PER_EC)
+ != 0) ? true : false;
+ o_info.readOnly = ((iv_TOC[id].misc & FFS_MISC_READ_ONLY)
+ != 0) ? true : false;
+// TODO securebootp9 the following field does not exist in p9. If the field is
+// to be added to p9 we need to enable this line at that time, or remove and
+// replace with appropriate code.
+// o_info.reprovision = ((iv_TOC[id].misc & FFS_MISC_REPROVISION)
+// != 0) ? true : false;
+ }
+
+ } while(0);
return l_errhdl;
}
diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C
new file mode 100644
index 000000000..71de27578
--- /dev/null
+++ b/src/usr/pnor/spnorrp.C
@@ -0,0 +1,948 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/pnor/spnorrp.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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 */
+#include "pnorrp.H"
+#include "spnorrp.H"
+#include <pnor/pnor_reasoncodes.H>
+#include <initservice/taskargs.H>
+#include <initservice/initserviceif.H>
+#include <sys/msg.h>
+#include <trace/interface.H>
+#include <errl/errlmanager.H>
+#include <sys/mm.h>
+#include <errno.h>
+#include <util/align.H>
+#include <config.h>
+#include "pnor_common.H"
+#include <console/consoleif.H>
+#include <secureboot/service.H>
+#include <secureboot/containerheader.H>
+#include <secureboot/trustedbootif.H>
+#include <secureboot/header.H>
+
+extern trace_desc_t* g_trac_pnor;
+
+// used to uniquley identify the secure PNOR RP message queue
+const char* SPNORRP_MSG_Q = "spnorrpq";
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+namespace PNOR
+{
+ //used by secure message queue for load/unload of secure PNOR sections
+ enum secure_msg_type
+ {
+ MSG_LOAD_SECTION = 0x02,
+ MSG_UNLOAD_SECTION = 0x03,
+ };
+};
+
+
+using namespace PNOR;
+
+/********************
+ Helper Methods
+ ********************/
+
+/**
+ * @brief Static function wrapper to pass into task_create
+ */
+void* secure_wait_for_message( void* unused )
+{
+ TRACUCOMP(g_trac_pnor, "wait_for_message> " );
+ Singleton<SPnorRP>::instance().waitForMessage();
+ return NULL;
+}
+
+
+/********************
+ Private/Protected Methods
+ ********************/
+
+/**
+ * @brief Constructor
+ */
+SPnorRP::SPnorRP()
+:
+iv_msgQ(NULL)
+,iv_startupRC(0)
+{
+ TRACFCOMP(g_trac_pnor, "SPnorRP::SPnorRP> " );
+ // setup everything in a separate function
+ initDaemon();
+
+ TRACFCOMP(g_trac_pnor, "< SPnorRP::PnorRP : Startup Errors=%X ", iv_startupRC );
+}
+
+/**
+ * @brief Destructor
+ */
+SPnorRP::~SPnorRP()
+{
+ TRACFCOMP(g_trac_pnor, "SPnorRP::~SPnorRP> " );
+
+ // delete the message queue we created
+ if( iv_msgQ )
+ {
+ msg_q_destroy( iv_msgQ );
+ }
+
+ // clean up the load records
+ for(std::map<SectionId, LoadRecord*>::iterator
+ i = iv_loadedSections.begin();
+ i != iv_loadedSections.end();
+ ++i)
+ {
+ LoadRecord* l_rec = (*i).second;
+ delete l_rec;
+ }
+
+ TRACFCOMP(g_trac_pnor, "< SPnorRP::~SPnorRP" );
+}
+
+/**
+ * @brief A wrapper for mm_alloc_block that encapsulates error log creation.
+ */
+errlHndl_t SPnorRP::allocBlock(msg_q_t i_mq, void* i_va, uint64_t i_size) const
+{
+ errlHndl_t l_errhdl = NULL;
+ int rc = mm_alloc_block(i_mq, i_va, i_size );
+ if( rc )
+ {
+ TRACFCOMP( g_trac_pnor,"SPnorRP::allocBlock> Error "
+ "with mm_alloc_block at address 0x%.16llX : rc=%d", i_va, rc );
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid PNOR::MOD_SPNORRP_ALLOCATE_BLOCK
+ * @reasoncode PNOR::RC_EXTERNAL_ERROR
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_alloc_block
+ * @devdesc SPnorRP::initDaemon> Error from mm_alloc_block
+ * @custdesc A problem occurred while initializing secure PNOR
+ */
+ l_errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ PNOR::MOD_SPNORRP_ALLOCATE_BLOCK,
+ PNOR::RC_EXTERNAL_ERROR,
+ TO_UINT64(reinterpret_cast<uint64_t>(i_va)),
+ TO_UINT64(rc),
+ true); //Add HB SW Callout
+ l_errhdl->collectTrace(PNOR_COMP_NAME);
+ l_errhdl->collectTrace(SECURE_COMP_NAME);
+ }
+ return l_errhdl;
+}
+
+/**
+ * @brief A wrapper for mm_set_permission that adds error log creation.
+ */
+errlHndl_t SPnorRP::setPermission(void* i_va, uint64_t i_size,
+ uint64_t i_accessType) const
+{
+ errlHndl_t l_errhdl = NULL;
+ int rc = mm_set_permission(reinterpret_cast<void*>(i_va), i_size,
+ i_accessType);
+ if ( rc )
+ {
+ TRACFCOMP( g_trac_pnor, "SPnorRP::setPermission> Error "
+ "with mm_set_permission at address 0x%.16llX : rc=%d",i_va, rc );
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid PNOR::MOD_SPNORRP_SET_PERMISSION
+ * @reasoncode PNOR::RC_EXTERNAL_ERROR
+ * @userdata1 Requested Address
+ * @userdata2 rc from mm_set_permission
+ * @devdesc Could not set permissions of the
+ * given PNOR section
+ * @custdesc A problem occurred while initializing secure PNOR
+ */
+ l_errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ PNOR::MOD_SPNORRP_SET_PERMISSION,
+ PNOR::RC_EXTERNAL_ERROR,
+ TO_UINT64(reinterpret_cast<uint64_t>(i_va)),
+ TO_UINT64(rc),
+ true); // Add HB SW Callout
+ l_errhdl->collectTrace(PNOR_COMP_NAME);
+ l_errhdl->collectTrace(SECURE_COMP_NAME);
+ }
+ return l_errhdl;
+}
+
+/**
+ * @brief Initialize the daemon
+ */
+void SPnorRP::initDaemon()
+{
+ TRACFCOMP(g_trac_pnor, "SPnorRP::initDaemon> " );
+ errlHndl_t l_errhdl = NULL;
+
+ do
+ {
+ // create a message queue for secure space
+ iv_msgQ = msg_q_create();
+
+ // register it so that it can be discovered by loadSecureSection()
+ int rc = msg_q_register(iv_msgQ, SPNORRP_MSG_Q);
+
+ assert(rc == 0);
+
+ // create a Block for temp space
+ l_errhdl = allocBlock( NULL, reinterpret_cast<void*>(TEMP_VADDR),
+ PNOR_SIZE );
+ if( l_errhdl )
+ {
+ break;
+ }
+
+ // set permissions for temp space
+ l_errhdl = setPermission(reinterpret_cast<void*>(TEMP_VADDR),
+ PNOR_SIZE, WRITABLE | ALLOCATE_FROM_ZERO);
+ if ( l_errhdl )
+ {
+ break;
+ }
+
+ // create a block for secure space
+ l_errhdl = allocBlock( iv_msgQ, reinterpret_cast<void*>(SBASE_VADDR),
+ PNOR_SIZE );
+ if( l_errhdl )
+ {
+ break;
+ }
+
+ // set permissions for secure space
+ l_errhdl = setPermission( reinterpret_cast<void*>(SBASE_VADDR),
+ PNOR_SIZE, NO_ACCESS);
+ if ( l_errhdl )
+ {
+ break;
+ }
+
+ // start task to wait on the queue
+ task_create( secure_wait_for_message, NULL );
+
+ } while(0);
+
+ if( l_errhdl )
+ {
+ iv_startupRC = l_errhdl->reasonCode();
+ errlCommit(l_errhdl,PNOR_COMP_ID);
+ }
+
+ TRACUCOMP(g_trac_pnor, "< SPnorRP::initDaemon" );
+}
+
+/**
+ * @brief Load secure sections into temporary address space and verify them
+ */
+void SPnorRP::verifySections(LoadRecord* o_rec, SectionId i_id)
+{
+ SectionInfo_t l_info;
+ errlHndl_t l_errhdl = NULL;
+ bool failedVerify = false;
+
+ do {
+ l_errhdl = getSectionInfo(i_id, l_info);
+
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,
+ "< SPnorrRP::verifySections - getSectionInfo failed");
+
+ break;
+ }
+ TRACDCOMP(g_trac_pnor,"SPnorRP::verifySections getSectionInfo"
+ " succeeded for sec = %s", l_info.name);
+
+ l_info.vaddr -= PAGESIZE; // back up a page to expose the secure header
+ l_info.size += PAGESIZE; // add a page to size to account for the header
+
+ // it's a coding error if l_info.vaddr is not in secure space
+ assert(l_info.vaddr >= SBASE_VADDR, "Virtual address for section %s is"
+ " not in secure space. Bad ptr=0x%X", l_info.name, l_info.vaddr);
+
+ // Note: A pointer to virtual memory in one PNOR space can be converted
+ // to a pointer to any of the other two PNOR spaces and visa versa.
+ // These are unsecured space, temp space, and secured space. They are
+ // evenly separated by VMM_VADDR_SPNOR_DELTA and in the above order.
+ // l_info.vaddr points to secure space, so we subtract a delta value
+ // from it to calculate its corresponding address in temp space.
+ uint8_t* l_tempAddr = reinterpret_cast<uint8_t*>(l_info.vaddr)
+ - VMM_VADDR_SPNOR_DELTA;
+
+ // calcluate unsecured address from temp address
+ uint8_t* l_unsecuredAddr = l_tempAddr - VMM_VADDR_SPNOR_DELTA;
+
+ TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections section start address "
+ "in temp space is 0x%.16llX, "
+ "section start address in unsecured space is 0x%.16llX, "
+ "l_info.size = 0x%.16llX, "
+ "payload size = 0x%.16llX, ",
+ l_tempAddr, l_unsecuredAddr, l_info.size,
+ l_info.secureProtectedPayloadSize);
+
+ TRACDBIN(g_trac_pnor,"SPnorRP::verifySections unsecured mem now: ",
+ l_unsecuredAddr, 128);
+
+ TRACDCOMP(g_trac_pnor,"SPnorRP::verifySections about to do memcpy");
+
+ // copy from unsecured PNOR space to temp PNOR space
+ memcpy(l_tempAddr, l_unsecuredAddr, l_info.secureProtectedPayloadSize
+ + PAGESIZE); // plus header size
+
+ SECUREBOOT::ContainerHeader l_conHdr(l_tempAddr);
+ size_t l_totalContainerSize = l_conHdr.totalContainerSize();
+
+ TRACDCOMP(g_trac_pnor, "SPnorRP::verifySections "
+ "Total container size = 0x%.16llX", l_totalContainerSize);
+
+ assert(l_totalContainerSize >= PAGESIZE +
+ + l_info.secureProtectedPayloadSize,
+ "For section %s, total container size (%d) was less than header "
+ "size (4096) + payload text size (%d)",
+ l_info.name,
+ l_totalContainerSize,
+ l_info.secureProtectedPayloadSize);
+
+ assert(l_info.size >= l_totalContainerSize,
+ "For section %s, logical section size (%d) was less than total "
+ "container size (%d)",
+ l_info.name,
+ l_info.size,
+ l_totalContainerSize);
+
+ TRACDCOMP(g_trac_pnor,"SPnorRP::verifySections did memcpy");
+ TRACDBIN(g_trac_pnor,"SPnorRP::verifySections temp mem now: ",
+ l_tempAddr, 128);
+
+ // store secure space pointer in load record
+ o_rec->secAddr = reinterpret_cast<uint8_t*>(l_info.vaddr) + PAGESIZE;
+
+ TRACFCOMP(g_trac_pnor,"section start address in secure space is "
+ "0x%.16llX",o_rec->secAddr);
+
+ // verify while in temp space
+ if (SECUREBOOT::enabled())
+ {
+ l_errhdl = SECUREBOOT::verifyContainer(l_tempAddr);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorrRP::verifySections - section "
+ "with id 0x%08X failed verifyContainer", i_id);
+ failedVerify = true;
+ break;
+ }
+
+ l_errhdl = miscSectionVerification(l_tempAddr, i_id);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorrRP::verifySections - section "
+ " with id 0x%08X failed miscSectionVerification", i_id);
+ failedVerify = true;
+ break;
+ }
+ }
+
+ // verification succeeded
+
+ // parse container header now that it is verified
+ // store the payload text size in the section load record
+ // Note: the text size we get back is now trusted
+ o_rec->textSize = l_conHdr.payloadTextSize();
+ l_totalContainerSize = l_conHdr.totalContainerSize();
+
+ assert(o_rec->textSize == l_info.secureProtectedPayloadSize);
+
+ // pcr extension of PNOR hash
+ l_errhdl = TRUSTEDBOOT::extendPnorSectionHash(l_conHdr,
+ (l_tempAddr + PAGESIZE),
+ i_id);
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections extendPnorSectionHash failed");
+ break;
+ }
+
+ // remove secure header page in temp space
+ mm_remove_pages(RELEASE, l_tempAddr, PAGESIZE);
+
+ // keep track of info size in load record
+ o_rec->infoSize = l_totalContainerSize - PAGESIZE;
+
+ // set permissions on the secured pages to writable
+ l_errhdl = setPermission(o_rec->secAddr, o_rec->textSize, WRITABLE);
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
+ "failed on text section");
+ break;
+ }
+
+ // set permissions on the unsecured pages to write tracked so that any
+ // unprotected payload pages with dirty writes can flow back to PNOR.
+ uint64_t unprotectedPayloadSize = l_totalContainerSize
+ - PAGESIZE - o_rec->textSize;
+ if (unprotectedPayloadSize) // only write track a non-zero range
+ {
+ TRACFCOMP(g_trac_pnor,INFO_MRK " SPnorRP::verifySections "
+ "creating unprotected area (%d bytes) for section %s",
+ unprotectedPayloadSize,
+ l_info.name);
+
+ // Split the mod math out of the assert as the trace would not
+ // display otherwise.
+ bool l_onPageBoundary = !(o_rec->textSize % PAGESIZE);
+ assert( l_onPageBoundary, "For section %s, payloadTextSize does "
+ "not fall on a page boundary and there is an unprotected "
+ "payload",
+ l_info.name);
+
+ l_errhdl = setPermission(o_rec->secAddr + o_rec->textSize,
+ unprotectedPayloadSize,
+ WRITABLE | WRITE_TRACKED);
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
+ "failed on data section");
+ break;
+ }
+
+ // Register the write tracked memory range to be flushed on
+ // shutdown.
+ INITSERVICE::registerBlock(o_rec->secAddr + o_rec->textSize,
+ unprotectedPayloadSize, SPNOR_PRIORITY);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_pnor,INFO_MRK " SPnorRP::verifySections not "
+ "creating unprotected area for section %s",
+ l_info.name);
+ }
+ TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
+ "and register block complete");
+ } while(0);
+
+ if( l_errhdl )
+ {
+ uint32_t l_errPlid = l_errhdl->plid();
+ iv_startupRC = l_errhdl->reasonCode();
+ TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections there was an error");
+ if (failedVerify)
+ {
+ TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections failed verify");
+ SECUREBOOT::handleSecurebootFailure(l_errhdl);
+ }
+ else
+ {
+ errlCommit(l_errhdl,PNOR_COMP_ID);
+ INITSERVICE::doShutdown(l_errPlid);
+ }
+ }
+}
+
+
+
+/**
+ * @brief Message receiver for secure space
+ */
+void SPnorRP::waitForMessage()
+{
+ TRACFCOMP(g_trac_pnor, "SPnorRP::waitForMessage>" );
+
+ errlHndl_t l_errhdl = NULL;
+ msg_t* message = NULL;
+ uint8_t* user_addr = NULL;
+ uint8_t* eff_addr = NULL;
+ int rc = 0;
+ uint64_t status_rc = 0;
+ LoadRecord l_rec;
+ l_rec.secAddr = NULL;
+ l_rec.textSize = 0;
+ l_rec.infoSize = 0;
+
+ while(1)
+ {
+ status_rc = 0;
+ TRACUCOMP(g_trac_pnor, "SPnorRP::waitForMessage> waiting for message" );
+ message = msg_wait( iv_msgQ );
+ if( message )
+ {
+ // data[0] = virtual address requested
+ // data[1] = address to place contents
+ eff_addr = reinterpret_cast<uint8_t*>(message->data[0]);
+ user_addr = reinterpret_cast<uint8_t*>(message->data[1]);
+
+ switch(message->type)
+ {
+ case( MSG_MM_RP_READ ):
+ {
+ uint64_t delta = VMM_VADDR_SPNOR_DELTA;
+
+ // check and see if our cached section information
+ // is obsolete and if so, change it
+ if ( (eff_addr < l_rec.secAddr) ||
+ (eff_addr >= (l_rec.secAddr + l_rec.infoSize))
+ )
+ {
+ bool l_found = false;
+ // recalculate addresses
+ for(std::map<SectionId, LoadRecord*>::const_iterator
+ i = iv_loadedSections.begin();
+ i != iv_loadedSections.end();
+ ++i)
+ {
+ LoadRecord* l_record = (*i).second;
+ if ( (eff_addr >= l_record->secAddr) &&
+ (eff_addr < (l_record->secAddr +
+ l_record->infoSize))
+ )
+ {
+ l_rec = *l_record;
+ l_found = true;
+ break;
+ }
+ }
+ if (!l_found)
+ {
+ TRACFCOMP( g_trac_pnor,
+ "SPnorRP::waitforMessage - address %p "
+ "out of bounds", eff_addr);
+ // not much we can do here unfortunately
+ // if we get here it is a coding mistake
+ status_rc = -EFAULT;
+ break;
+ }
+
+ }
+
+ TRACDCOMP( g_trac_pnor, "SPnorRP::waitForMessage got a"
+ " request to read from secure space - "
+ "message : user_addr=%p, eff_addr=%p, msgtype=%d, "
+ "textSize=0x%.16llX secAddr0x%.16llX", user_addr,
+ eff_addr, message->type, l_rec.textSize,
+ l_rec.secAddr);
+
+ // determine the source of the data depending on
+ // whether it is part of the secure payload.
+ // by the way, this if could be removed to make this
+ // purely arithmetic
+ if (eff_addr >= (l_rec.secAddr + l_rec.textSize))
+ {
+ delta += VMM_VADDR_SPNOR_DELTA;
+ }
+ TRACDCOMP( g_trac_pnor, "SPnorRP::waitForMessage "
+ "source address: %p", eff_addr - delta);
+
+ // depending on the value of delta, memcpy from either
+ // temp space or unsecured pnor space over to secure
+ // pnor space
+ memcpy(user_addr, eff_addr - delta, PAGESIZE);
+ // if the page came from temp space then free up
+ // the temp page now that we're done with it
+ if (eff_addr < (l_rec.secAddr + l_rec.textSize))
+ {
+ mm_remove_pages(RELEASE, eff_addr - delta,
+ PAGESIZE);
+ }
+ }
+ break;
+
+ case( MSG_MM_RP_WRITE ):
+ {
+ TRACDCOMP( g_trac_pnor, "SPnorRP::waitForMessage "
+ "writing to an unsecured area of section.");
+
+ // calculate unsecured address (in PnorRP) by
+ // subtracting two deltas from secure address
+ uint8_t* dest = eff_addr - VMM_VADDR_SPNOR_DELTA
+ - VMM_VADDR_SPNOR_DELTA;
+ memcpy(dest, user_addr, PAGESIZE);
+ }
+ break;
+
+ case( PNOR::MSG_LOAD_SECTION ):
+ {
+ SectionId l_id =
+ static_cast<SectionId>(message->data[0]);
+ if (iv_loadedSections[l_id] == NULL)
+ {
+ LoadRecord* l_record = new LoadRecord;
+ verifySections(l_record,l_id);
+ iv_loadedSections[l_id] = l_record;
+
+ // cache the record to use fields later as hints
+ l_rec = *l_record;
+ }
+ }
+ break;
+
+ default:
+ TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::waitForMessage> "
+ "Unrecognized message type : user_addr=%p, eff_addr=%p,"
+ " msgtype=%d", user_addr, eff_addr, message->type );
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid PNOR::MOD_SPNORRP_WAITFORMESSAGE
+ * @reasoncode PNOR::RC_INVALID_MESSAGE_TYPE
+ * @userdata1 Message type
+ * @userdata2 Requested Virtual Address
+ * @devdesc PnorRP::waitForMessage> Unrecognized
+ * message type
+ * @custdesc A problem occurred while accessing
+ * the boot flash.
+ */
+ l_errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ PNOR::MOD_SPNORRP_WAITFORMESSAGE,
+ PNOR::RC_INVALID_MESSAGE_TYPE,
+ TO_UINT64(message->type),
+ reinterpret_cast<uint64_t>(eff_addr),
+ true /*Add HB SW Callout*/);
+ l_errhdl->collectTrace(PNOR_COMP_NAME);
+ l_errhdl->collectTrace(SECURE_COMP_NAME);
+ status_rc = -EINVAL; /* Invalid argument */
+ }
+
+ assert(msg_is_async(message) == false);
+
+ if( l_errhdl )
+ {
+ errlCommit(l_errhdl,PNOR_COMP_ID);
+ }
+
+ /* Expected Response:
+ * data[0] = virtual address requested or
+ * section id (if load message)
+ * data[1] = rc (0 or negative errno value)
+ * extra_data = Specific reason code.
+ */
+ message->data[1] = status_rc;
+ message->extra_data = 0;
+ rc = msg_respond( iv_msgQ, message );
+ if( rc )
+ {
+ TRACFCOMP(g_trac_pnor,
+ "SPnorRP::waitForMessage> Error from msg_respond, "
+ "giving up : rc=%d", rc );
+ break;
+ }
+ }
+ assert(message != NULL);
+ }
+
+ TRACFCOMP(g_trac_pnor, "< SPnorRP::waitForMessage" );
+}
+
+/**
+ * @brief Loads requested PNOR section to secure virtual address space
+ */
+errlHndl_t PNOR::loadSecureSection(const SectionId i_section)
+{
+ // Send message to secure provider to load the section
+ errlHndl_t err = NULL;
+
+ if (!isSecureSection(i_section))
+ {
+ TRACFCOMP(g_trac_pnor,ERR_MRK"PNOR::loadSecureSection> called on "
+ "unsecured section");
+ // TODO securebootp9 remove below temporary code after all of the
+ // sections in the below if condition have been fully ported and added
+ // to isSecureSection.
+ // start temporary code
+ if (i_section == PNOR::HB_EXT_CODE ||
+ i_section == PNOR::HB_DATA ||
+ i_section == PNOR::SBE_IPL ||
+ i_section == PNOR::CENTAUR_SBE ||
+ i_section == PNOR::PAYLOAD ||
+ i_section == PNOR::OCC ||
+ i_section == PNOR::HB_RUNTIME)
+ {
+ // For now, ignore the attempt to load this section securely.
+ // Returning from the middle of a function is excusable because
+ // it keeps the temp code in one place, making it easier to remove.
+ return NULL;
+ }
+ // end temporary code
+ // TODO securebootp9 revisit this assert code and replace with error log
+ // code if it is deemed that this assert could happen in the field
+ assert(false,"PNOR::loadSection> section %i is not a secure section",
+ i_section);
+ }
+
+ msg_q_t spnorQ = msg_q_resolve(SPNORRP_MSG_Q);
+
+ assert(spnorQ != NULL);
+
+ msg_t* msg = msg_allocate();
+
+ assert(msg != NULL);
+
+ msg->type = PNOR::MSG_LOAD_SECTION;
+ msg->data[0] = static_cast<uint64_t>(i_section);
+ int rc = msg_sendrecv(spnorQ, msg);
+
+ TRACFCOMP(g_trac_pnor, "loadSecureSection i_section = %i",i_section);
+
+ // TODO securebootp9 - Need to be able to receive an error from the
+ // message handler. Also, message handler should police whether the request
+ // is for a secure section or not and throw an error accordingly.
+ //if (0 == rc)
+ //{
+ // err = reinterpret_cast<errlHndl_t>(msg->data[1]);
+ //}
+ //else remove the if clause below at some point
+ if (rc != 0)
+ {
+
+ TRACFCOMP(g_trac_pnor,ERR_MRK"PNOR::loadSecureSection> Error from msg_sendrecv rc=%d",
+ rc );
+ /* @errorlog
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MOD_PNORRP_LOADSECURESECTION
+ * @reasoncode RC_EXTERNAL_ERROR
+ * @userdata1 returncode from msg_sendrecv()
+ * @userdata2[0:31] SPNOR message type [LOAD | UNLOAD]
+ * @userdata2[32:63] Section ID
+ * @devdesc Could not load/unload section.
+ * @custdesc Security failure: unable to securely load
+ * requested firmware.
+ */
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MOD_PNORRP_LOADSECURESECTION,
+ RC_EXTERNAL_ERROR,
+ rc,
+ TWO_UINT32_TO_UINT64(PNOR::MSG_LOAD_SECTION,
+ i_section),
+ true /* Add HB Software Callout */);
+ err->collectTrace(PNOR_COMP_NAME);
+ }
+ msg_free(msg);
+
+ return err;
+}
+
+/**
+ * @brief Flushes any applicable pending writes and unloads requested PNOR
+ * section from secure virtual address space
+ */
+errlHndl_t PNOR::unloadSecureSection(const SectionId i_section)
+{
+ // @TODO RTC 156118
+ // Replace with call to secure provider to unload the section
+ errlHndl_t pError=NULL;
+ return pError;
+}
+
+errlHndl_t SPnorRP::miscSectionVerification(const uint8_t *i_vaddr,
+ SectionId i_secId) const
+{
+ errlHndl_t l_errl = NULL;
+ assert(i_vaddr != NULL);
+
+ TRACFCOMP(g_trac_pnor, "SPnorRP::miscSectionVerification section=%d", i_secId);
+
+// TODO securebootp9 - remove the following #if 0 and address issues
+#if 0
+ // Do any additional verification needed for a specific PNOR section
+ switch (i_secId) {
+ case HB_EXT_CODE:
+ // Compare HBB and HBI versions. Pass the vaddr of HBI's hash page
+ // table by skipping past the container header.
+ l_errl = baseExtVersCheck((i_vaddr + PAGESIZE));
+ break;
+ case SBKT:
+ // Ensure the SBKT partition has a valid key transition container
+ // Add PAGESIZE to skip outer container
+ l_errl = keyTransitionCheck((i_vaddr + PAGESIZE));
+ break;
+ default:
+ break;
+ }
+#endif
+ return l_errl;
+}
+
+errlHndl_t SPnorRP::baseExtVersCheck(const uint8_t *i_vaddr) const
+{
+ errlHndl_t l_errl = NULL;
+ assert(i_vaddr != NULL);
+
+ // Check if measured and build time hashes of HBB sw signatures match.
+ // Query the HBB header
+ const void* l_pHbbHeader = NULL;
+ SECUREBOOT::baseHeader().getHeader(l_pHbbHeader);
+ // Fatal code bug if either address is NULL
+ assert(l_pHbbHeader!=NULL,"ERORR: Cached header address is NULL");
+ // Build a container header object from the raw header
+ SECUREBOOT::ContainerHeader l_hbbContainerHeader(l_pHbbHeader);
+
+ // Calculate hash of HBB's sw signatures
+ SHA512_t l_hashSwSigs = {0};
+
+ SECUREBOOT::hashBlob(l_hbbContainerHeader.sw_sigs(),
+ l_hbbContainerHeader.totalSwKeysSize(),
+ l_hashSwSigs);
+
+ // Get build time hash of HBB's sw signatures. The hash of HBB's sw
+ // signatures are stored in the first entry (SALT) of HBI's hash page
+ // table. The first entry of HBI's hash pagle starts immediately after the
+ // header so we can simply cast the vaddr to get our first entry (SALT)
+ // Note: It is expected that i_vaddr points to the start of HBI's hash
+ // page table.
+ const PAGE_TABLE_ENTRY_t* l_hashPageTableSaltEntry =
+ reinterpret_cast<const PAGE_TABLE_ENTRY_t*>(i_vaddr);
+
+ // Throw an error if the hashes do not match to the truncated length
+ // of a hash page table entry.
+ if ( memcmp(l_hashSwSigs, l_hashPageTableSaltEntry,
+ HASH_PAGE_TABLE_ENTRY_SIZE) != 0 )
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::baseExtVersCheck Hostboot Base and Extended image mismatch");
+ TRACFBIN(g_trac_pnor,"SPnorRP::baseExtVersCheck Measured sw key hash",
+ l_hashSwSigs, HASH_PAGE_TABLE_ENTRY_SIZE);
+ TRACFBIN(g_trac_pnor,"SPnorRP::baseExtVersCheck HBI's hash page table salt entry",
+ l_hashPageTableSaltEntry, HASH_PAGE_TABLE_ENTRY_SIZE);
+
+ // Memcpy needed for measured hash to avoid gcc error: dereferencing
+ // type-punned pointer will break strict-aliasing rules
+ uint64_t l_measuredHash = 0;
+ memcpy(&l_measuredHash, l_hashSwSigs, sizeof(l_measuredHash));
+ /*@ errorlog
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MOD_SPNORRP_BASE_EXT_VER_CHK
+ * @reasoncode RC_BASE_EXT_MISMATCH
+ * @userdata1 First 8 bytes of hash of measured SW signatures
+ * @userdata2 First 8 bytes of hash of stored SW signatures in
+ * hash page table
+ * @devdesc Hostboot Base and Extend code do not match versions.
+ * @custdesc Firmware level mismatch.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MOD_SPNORRP_BASE_EXT_VER_CHK,
+ RC_BASE_EXT_MISMATCH,
+ l_measuredHash,
+ TO_UINT64(*reinterpret_cast<const uint64_t*>(l_hashPageTableSaltEntry)));
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ }
+
+ return l_errl;
+}
+
+errlHndl_t SPnorRP::keyTransitionCheck(const uint8_t *i_vaddr) const
+{
+ errlHndl_t l_errl = NULL;
+ assert(i_vaddr != NULL);
+
+ do {
+ // Check if the header flags have the key transition bit set
+ SECUREBOOT::ContainerHeader l_nestedConHdr(i_vaddr);
+ if (!l_nestedConHdr.sb_flags()->hw_key_transition)
+ {
+ TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck() - Key transition flag not set");
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MOD_SPNORRP_KEY_TRAN_CHK
+ * @reasoncode RC_KEY_TRAN_FLAG_UNSET
+ * @userdata1 0
+ * @userdata2 0
+ * @devdesc Key transition flag not set in nested SBKT container containing new hw keys
+ * @custdesc Secureboot key transition failure
+ */
+ l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MOD_SPNORRP_KEY_TRAN_CHK,
+ RC_KEY_TRAN_FLAG_UNSET,
+ 0,
+ 0,
+ true /*Add HB Software Callout*/ );
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ break;
+ }
+
+// TODO securebootp9 - remove the following #if 0 and address issues
+#if 1
+ // Validate nested container is properly signed using new hw keys
+ l_errl = SECUREBOOT::verifyContainer(const_cast<uint8_t*>(i_vaddr),
+ l_nestedConHdr.hwKeyHash());
+ if (l_errl)
+ {
+ TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck() - failed verifyContainer");
+ break;
+ }
+#endif
+ }while(0);
+
+ return l_errl;
+}
+
+bool PNOR::cmpSecurebootMagicNumber(const uint8_t* i_vaddr)
+{
+ return memcmp(&MAGIC_NUMBER, i_vaddr, sizeof(MAGIC_NUMBER)) == 0;
+}
+
+errlHndl_t PNOR::hasSecurebootMagicNumber(const SectionId i_section,
+ bool &o_valid)
+{
+ errlHndl_t l_errl = NULL;
+ SectionInfo_t l_info;
+
+ // Force to false
+ o_valid = false;
+
+ // This will not work for HBB
+ assert(i_section != HB_BASE_CODE, "hasSecurebootMagicNumber() does not work for HBB section");
+
+ bool isSecure = PNOR::isSecureSection(i_section);
+ do {
+ l_errl = getSectionInfo(i_section, l_info);
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"PNOR::hasSecurebootMagicNumber(): - getSectionInfo failed");
+ break;
+ }
+
+ // Use PNOR vaddr
+ if(isSecure)
+ {
+ // back up a page to expose the secure header
+ l_info.vaddr = l_info.vaddr - VMM_VADDR_SPNOR_DELTA
+ - VMM_VADDR_SPNOR_DELTA
+ - PAGESIZE;
+ }
+ o_valid = cmpSecurebootMagicNumber(reinterpret_cast<uint8_t*>
+ (l_info.vaddr));
+ }while(0);
+
+ return l_errl;
+}
+
diff --git a/src/usr/pnor/spnorrp.H b/src/usr/pnor/spnorrp.H
new file mode 100644
index 000000000..9f7e533d5
--- /dev/null
+++ b/src/usr/pnor/spnorrp.H
@@ -0,0 +1,190 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/pnor/spnorrp.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
+/* [+] 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 __PNOR_SPNORRP_H
+#define __PNOR_SPNORRP_H
+#include <pnor/pnorif.H>
+#include <sys/msg.h>
+#include <stdint.h>
+#include <builtins.h>
+#include <errl/errlentry.H>
+#include <vmmconst.h>
+#include <map>
+#include "pnor_common.H"
+#include "ffs.h"
+#include <config.h>
+
+/**
+ * Secure PNOR Resource Provider
+ */
+
+class SPnorRP
+{
+ public:
+ /**
+ * @brief Static Initializer
+ * @param[in] ref to errlHndl_t
+ */
+ static void init( errlHndl_t &io_rtaskRetErrl );
+
+ /**
+ * @brief Returns true if the initial startup failed for some reason
+ * @param[out] Return code
+ * @return true if startup failed
+ */
+ bool didStartupFail( uint64_t& o_rc ) const
+ {
+ if( iv_startupRC )
+ {
+ o_rc = iv_startupRC;
+ return true;
+ }
+ return false;
+ };
+
+
+ protected:
+ /**
+ * @brief Constructor, default TOC offsets to side A
+ */
+ SPnorRP();
+
+ /**
+ * @brief Destructor
+ */
+ ~SPnorRP();
+
+ private:
+
+ enum
+ {
+ SBASE_VADDR = VMM_VADDR_SPNOR_RP, /**< 8GB = 0x200000000*/
+ TEMP_VADDR = VMM_VADDR_SPNOR_TEMP, /**< 5GB = 0x140000000 */
+ LAST_VADDR = SBASE_VADDR + PNOR::PNOR_SIZE, /**< End of our VA range */
+ };
+
+ /* bitwise enumeration to keep track of verified sections */
+ enum
+ {
+ HBI_SECTION = 0x1,
+ };
+
+ /**
+ * Pointer to the message queue where we receive messages for
+ * secure space.
+ */
+ msg_q_t iv_msgQ;
+
+ /**
+ * Remember that we failed during initial startup
+ * This is set by startup methods to indicate to constructor that
+ * something went wrong
+ */
+ uint64_t iv_startupRC;
+
+ /**
+ * Keep track of secured payload size and secure section addresses
+ */
+ struct LoadRecord{
+ uint8_t* secAddr;
+ size_t textSize;
+ size_t infoSize;
+ };
+ std::map<PNOR::SectionId, LoadRecord*> iv_loadedSections;
+
+
+ /**
+ * @brief Initialize the daemon, called by constructor
+ */
+ void initDaemon();
+
+ /**
+ * @brief Load secure sections into temporary address space and verify them
+ */
+ void verifySections(LoadRecord* o_rec, PNOR::SectionId i_id);
+
+ /**
+ * @brief Message receiver for secure space
+ */
+ void waitForMessage();
+
+ // disable copy ctor
+ SPnorRP(const SPnorRP&);
+
+ // disable assignment operator
+ SPnorRP& operator=(const SPnorRP&);
+
+ // allow local helper function to call private methods
+ friend void* secure_wait_for_message( void* unused );
+
+ /**
+ * @brief A wrapper for mm_alloc_block that encapsulates error log
+ * creation.
+ */
+ errlHndl_t allocBlock(msg_q_t mq, void* va, uint64_t size) const;
+
+ /**
+ * @brief A wrapper for mm_set_permission that encapsulates error log
+ * creation.
+ */
+ errlHndl_t setPermission(void* va, uint64_t size,
+ uint64_t accessType) const;
+
+ /**
+ * @brief Handles any additional section specific verification checks.
+ * @param[in] i_vaddr - vaddr of PNOR section to verify. Includes header
+ * NULL will assert
+ * @param[in] i_secId - PNOR section id to verify
+ * @return errlHndl_t - NULL if success, errlHndl_t otherwise.
+ */
+ errlHndl_t miscSectionVerification(const uint8_t *i_vaddr,
+ PNOR::SectionId i_secId) const;
+
+ /**
+ * @brief Check if HBB and HBI were part of the same build
+ * Calculate HBB sw signatures hash and compare that to the build
+ * time hash of HBB sw signatures. The build time HBB hash is stored
+ * in the first entry (SALT) of HBI's hash page table.
+ * @param[in] i_vaddr - vaddr points to start of hash page table of HBI
+ * NOTE: Since this expects the vaddr to point to the
+ * start of the hash page table, the secureboot header
+ * must be skipped prior by the caller.
+ * NULL will assert
+ * @return errlHndl_t - NULL if success, errlHndl_t otherwise.
+ */
+ errlHndl_t baseExtVersCheck(const uint8_t *i_vaddr) const;
+
+ /**
+ * @brief Check if SBKT is properly formatted to then provide the new HW
+ * key hash to transition the system to.
+ * @param[in] i_vaddr - vaddr points to start SBKT's nested container
+ * NOTE: Since this expects the vaddr to point to the
+ * start of the nested container, the outer secureboot
+ * header must be skipped prior by the caller.
+ * NULL will assert
+ * @return errlHndl_t - NULL if success, errlHndl_t otherwise.
+ */
+ errlHndl_t keyTransitionCheck(const uint8_t *i_vaddr) const;
+};
+#endif
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index 8222063a6..bd0c8bc9d 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -814,10 +814,15 @@ class PnorRpTest : public CxxTest::TestSuite
// APIs are callable; they should return success always
// until 156118 implements the real support. At that time
// this testcase should be updated.
+#ifdef CONFIG_SECUREBOOT
errlHndl_t pError=NULL;
-
do {
+ if (!PNOR::isSecureSection(PNOR::SBE_IPL))
+ {
+ break;
+ }
+
pError = PNOR::loadSecureSection(PNOR::SBE_IPL);
if(pError != NULL)
{
@@ -837,6 +842,7 @@ class PnorRpTest : public CxxTest::TestSuite
}
} while (0);
+#endif
}
};
diff --git a/src/usr/secureboot/base/containerheader.C b/src/usr/secureboot/base/containerheader.C
new file mode 100644
index 000000000..5f8e2fdc7
--- /dev/null
+++ b/src/usr/secureboot/base/containerheader.C
@@ -0,0 +1,248 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/secureboot/base/containerheader.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] 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 */
+#include <secureboot/containerheader.H>
+
+extern trace_desc_t* g_trac_secure;
+
+// Quick change for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+namespace SECUREBOOT
+{
+
+void ContainerHeader::parse_header(const void* i_header)
+{
+ assert(i_header != NULL);
+ const uint8_t* l_hdr = reinterpret_cast<const uint8_t*>(i_header);
+
+ /*---- Parse ROM_container_raw ----*/
+ // The rom code has a placeholder for the prefix in the first struct
+ size_t l_size = offsetof(ROM_container_raw, prefix);
+ safeMemCpyAndInc(&iv_headerInfo.hw_hdr, l_hdr, l_size);
+
+ // Early check if magic number is valid, as a quick check to try and prevent
+ // any storage exceptions while parsing header.
+ assert(iv_headerInfo.hw_hdr.magic_number == MAGIC_NUMBER,
+ "ContainerHeader: magic number = 0x%08X not valid",
+ iv_headerInfo.hw_hdr.magic_number);
+
+ /*---- Parse ROM_prefix_header_raw ----*/
+ l_size = offsetof(ROM_prefix_header_raw, ecid);
+ safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr, l_hdr, l_size);
+
+ // Get ECID array
+ l_size = iv_headerInfo.hw_prefix_hdr.ecid_count * ECID_SIZE;
+ safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr.ecid, l_hdr, l_size);
+
+ /*---- Parse ROM_prefix_data_raw ----*/
+ l_size = offsetof(ROM_prefix_data_raw, sw_pkey_p);
+ safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data, l_hdr, l_size);
+
+ // Get SW keys
+ l_size = iv_headerInfo.hw_prefix_hdr.sw_key_count * sizeof(ecc_key_t);
+ // Cache total software keys size
+ iv_totalSwKeysSize = l_size;
+ safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data.sw_pkey_p, l_hdr, l_size);
+
+ /*---- Parse ROM_sw_header_raw ----*/
+ l_size = offsetof(ROM_sw_header_raw, ecid);
+ safeMemCpyAndInc(&iv_headerInfo.sw_hdr, l_hdr, l_size);
+
+ // Get ECID array
+ l_size = iv_headerInfo.sw_hdr.ecid_count * ECID_SIZE;
+ safeMemCpyAndInc(&iv_headerInfo.sw_hdr.ecid, l_hdr, l_size);
+
+ /*---- Parse ROM_sw_sig_raw ----*/
+ safeMemCpyAndInc(&iv_headerInfo.sw_sig.sw_sig_p, l_hdr, iv_totalSwKeysSize);
+
+ // Parse hw and sw flags
+ parseFlags();
+
+ // Generate hw hash key
+ genHwKeyHash();
+
+ // After parsing check if header is valid, do some quick bound checks
+ validate();
+
+ // Debug printing
+ print();
+}
+
+void ContainerHeader::print() const
+{
+#ifdef HOSTBOOT_DEBUG
+ TRACFCOMP(g_trac_secure, ENTER_MRK"ContainerHeader::print");
+
+ TRACFCOMP(g_trac_secure,"header content size 0x%X", iv_hdrBytesRead);
+
+ /*---- Print ROM_container_raw ----*/
+ TRACFCOMP(g_trac_secure,"magic_number 0x%X", iv_headerInfo.hw_hdr.magic_number);
+ TRACFCOMP(g_trac_secure,"version 0x%X", iv_headerInfo.hw_hdr.version);
+ TRACFCOMP(g_trac_secure,"container_size 0x%X", iv_headerInfo.hw_hdr.container_size);
+ TRACFCOMP(g_trac_secure,"target_hrmor 0x%X", iv_headerInfo.hw_hdr.target_hrmor);
+ TRACFCOMP(g_trac_secure,"stack_pointer 0x%X", iv_headerInfo.hw_hdr.stack_pointer);
+ TRACFBIN(g_trac_secure,"hw_pkey_a", iv_headerInfo.hw_hdr.hw_pkey_a, 64);
+ TRACFBIN(g_trac_secure,"hw_pkey_b", iv_headerInfo.hw_hdr.hw_pkey_b, 64);
+ TRACFBIN(g_trac_secure,"hw_pkey_c", iv_headerInfo.hw_hdr.hw_pkey_c, 64);
+
+ /*---- Print ROM_prefix_header_raw ----*/
+ TRACFCOMP(g_trac_secure,"hw_flags 0x%X", iv_headerInfo.hw_prefix_hdr.flags);
+ TRACFCOMP(g_trac_secure,"sw_key_count 0x%X", iv_headerInfo.hw_prefix_hdr.sw_key_count);
+ TRACFBIN(g_trac_secure,"sw public key hash", iv_headerInfo.hw_prefix_hdr.payload_hash, SHA512_DIGEST_LENGTH);
+
+ /*---- Print ROM_prefix_data_raw ----*/
+ TRACFBIN(g_trac_secure,"sw_pkey_p", iv_headerInfo.hw_prefix_data.sw_pkey_p, sizeof(ecc_key_t));
+ if (iv_headerInfo.hw_prefix_hdr.sw_key_count>1)
+ {
+ TRACFBIN(g_trac_secure,"sw_pkey_q", iv_headerInfo.hw_prefix_data.sw_pkey_q, sizeof(ecc_key_t));
+ }
+ if (iv_headerInfo.hw_prefix_hdr.sw_key_count>2)
+ {
+ TRACFBIN(g_trac_secure,"sw_pkey_r", iv_headerInfo.hw_prefix_data.sw_pkey_r, sizeof(ecc_key_t));
+ }
+
+ /*---- Print ROM_sw_header_raw ----*/
+ TRACFCOMP(g_trac_secure,"payload_size 0x%X", iv_headerInfo.sw_hdr.payload_size );
+ TRACFBIN(g_trac_secure,"payload_hash", iv_headerInfo.sw_hdr.payload_hash, SHA512_DIGEST_LENGTH);
+
+ /*---- Print ROM_sw_sig_raw ----*/
+ TRACFBIN(g_trac_secure,"sw_sig_p", iv_headerInfo.sw_sig.sw_sig_p, sizeof(ecc_key_t));
+ if (iv_headerInfo.hw_prefix_hdr.sw_key_count>1)
+ {
+ TRACFBIN(g_trac_secure,"sw_sig_q", iv_headerInfo.sw_sig.sw_sig_q, sizeof(ecc_key_t));
+ }
+ if (iv_headerInfo.hw_prefix_hdr.sw_key_count>2)
+ {
+ TRACFBIN(g_trac_secure,"sw_sig_r", iv_headerInfo.sw_sig.sw_sig_r, sizeof(ecc_key_t));
+ }
+
+ TRACFCOMP(g_trac_secure, EXIT_MRK"ContainerHeader::print");
+#endif
+}
+
+size_t ContainerHeader::totalContainerSize() const
+{
+ return iv_headerInfo.hw_hdr.container_size;
+}
+
+const ecc_key_t* ContainerHeader::hw_keys() const
+{
+ return &iv_headerInfo.hw_hdr.hw_pkey_a;
+}
+
+size_t ContainerHeader::payloadTextSize() const
+{
+ return iv_headerInfo.sw_hdr.payload_size;
+}
+
+const SHA512_t* ContainerHeader::payloadTextHash() const
+{
+ return &iv_headerInfo.sw_hdr.payload_hash;
+}
+
+size_t ContainerHeader::totalSwKeysSize() const
+{
+ return iv_totalSwKeysSize;
+}
+
+const ecc_key_t* ContainerHeader::sw_keys() const
+{
+ return &iv_headerInfo.hw_prefix_data.sw_pkey_p;
+}
+
+const SHA512_t* ContainerHeader::swKeyHash() const
+{
+ return &iv_headerInfo.hw_prefix_hdr.payload_hash;
+}
+
+const ecc_key_t* ContainerHeader::sw_sigs() const
+{
+ return &iv_headerInfo.sw_sig.sw_sig_p;
+}
+
+const sb_flags_t* ContainerHeader::sb_flags() const
+{
+ return &iv_sbFlags;
+}
+
+const SHA512_t* ContainerHeader::hwKeyHash() const
+{
+ return &iv_hwKeyHash;
+}
+
+void ContainerHeader::validate()
+{
+ iv_isValid = (iv_hdrBytesRead <= MAX_SECURE_HEADER_SIZE)
+ && (iv_headerInfo.hw_hdr.magic_number == MAGIC_NUMBER)
+ && (iv_headerInfo.hw_hdr.version == ROM_VERSION)
+ && (iv_headerInfo.hw_prefix_hdr.ver_alg.version == ROM_VERSION)
+ && (iv_headerInfo.hw_prefix_hdr.ver_alg.hash_alg == ROM_HASH_ALG)
+ && (iv_headerInfo.hw_prefix_hdr.ver_alg.sig_alg == ROM_SIG_ALG)
+ && (iv_headerInfo.hw_prefix_hdr.sw_key_count >= SW_KEY_COUNT_MIN)
+ && (iv_headerInfo.hw_prefix_hdr.sw_key_count <= SW_KEY_COUNT_MAX)
+ && (iv_headerInfo.sw_hdr.payload_size != 0);
+}
+
+void ContainerHeader::safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
+ const size_t i_size)
+{
+ assert(i_dest != NULL, "ContainerHeader: dest ptr NULL");
+ assert(io_hdr != NULL, "ContainerHeader: current header location ptr NULL");
+ assert(iv_pHdrStart != NULL, "ContainerHeader: start of header ptr NULL");
+
+ TRACDCOMP(g_trac_secure,"dest: 0x%X src: 0x%X size: 0x%X",i_dest, io_hdr, i_size);
+
+ // Determine if the memcpy is within the bounds of the container header
+ iv_hdrBytesRead = io_hdr - iv_pHdrStart;
+ assert( (iv_hdrBytesRead + i_size) <= MAX_SECURE_HEADER_SIZE,
+ "ContainerHeader: memcpy is out of bounds of max header size");
+
+ memcpy(i_dest, io_hdr, i_size);
+ io_hdr += i_size;
+}
+
+bool ContainerHeader::isValid() const
+{
+ return iv_isValid;
+}
+
+void ContainerHeader::parseFlags()
+{
+ iv_sbFlags.hw_hb_fw = iv_headerInfo.hw_prefix_hdr.flags & HB_FW_FLAG;
+ iv_sbFlags.hw_opal = iv_headerInfo.hw_prefix_hdr.flags & OPAL_FLAG;
+ iv_sbFlags.hw_phyp = iv_headerInfo.hw_prefix_hdr.flags & PHYP_FLAG;
+ iv_sbFlags.hw_key_transition = iv_headerInfo.hw_prefix_hdr.flags
+ & KEY_TRANSITION_FLAG;
+}
+
+void ContainerHeader::genHwKeyHash()
+{
+ // Generate and store hw hash key
+ SECUREBOOT::hashBlob(&iv_headerInfo.hw_hdr.hw_pkey_a,
+ totalHwKeysSize, iv_hwKeyHash);
+}
+
+}; //end of SECUREBOOT namespace
diff --git a/src/usr/secureboot/base/header.C b/src/usr/secureboot/base/header.C
index 23cefcf84..37ba7ca72 100644
--- a/src/usr/secureboot/base/header.C
+++ b/src/usr/secureboot/base/header.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* [+] 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. */
@@ -20,13 +22,21 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-#include "header.H"
+#include <secureboot/header.H>
#include <sys/mm.h>
#include <sys/mmio.h>
#include <kernel/console.H>
namespace SECUREBOOT
{
+ Header& baseHeader()
+ {
+ 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()
{
// Calculate original address of the secureboot header.
@@ -54,4 +64,23 @@ namespace SECUREBOOT
return;
}
+
+ // TODO securebootp9 this implementation of the follwoing two methods need
+ // to be added based on p8 code
+ void Header::loadSecurely()
+ {
+ }
+
+ void Header::setNonSecurely(
+ const void* i_pHeader)
+ {
+ }
+
+ void Header::getHeader(
+ const void*& o_pHeader ) const
+ {
+ // Fatal code bug if queried before loaded
+ assert(iv_data!=nullptr);
+ o_pHeader = iv_data;
+ }
}
diff --git a/src/usr/secureboot/base/makefile b/src/usr/secureboot/base/makefile
index 1c13cc289..e2b143978 100644
--- a/src/usr/secureboot/base/makefile
+++ b/src/usr/secureboot/base/makefile
@@ -24,6 +24,7 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
MODULE = secureboot_base
+include ../common/common.mk
SUBDIRS += test.d
OBJS += service.o
@@ -33,6 +34,10 @@ OBJS += securerom.o
OBJS += rom_entry.o
OBJS += trustedboot_base.o
OBJS += $(if $(CONFIG_TPMDD),trustedbootMsg.o,)
+OBJS += containerheader.o
+OBJS += ${SECUREBOOT_COMMON_OBJS}
+
+VPATH += ../common
EXTRAINCDIR += ${ROOTPATH}/src/usr/secureboot/trusted/base
VPATH += ${ROOTPATH}/src/usr/secureboot/trusted/base
diff --git a/src/usr/secureboot/base/securerom.C b/src/usr/secureboot/base/securerom.C
index 82a72c185..dd859c6ab 100644
--- a/src/usr/secureboot/base/securerom.C
+++ b/src/usr/secureboot/base/securerom.C
@@ -62,23 +62,27 @@ errlHndl_t initializeSecureROM(void)
return Singleton<SecureROM>::instance().initialize();
}
+
+// TODO securebootp9 - the method signature below was brought in from
+// p8. There are many more changes need to this file however, in order to
+// be considered up-to-date.
/**
* @brief Verify Signed Container
*/
-errlHndl_t verifyContainer(void * i_container, size_t i_size)
+errlHndl_t verifyContainer(void * i_container, const sha2_hash_t* i_hwKeyHash)
{
TRACUCOMP(g_trac_secure, "verifyContainer(): i_container=%p, size=0x%x",
i_container, i_size);
return Singleton<SecureROM>::instance().verifyContainer(i_container,
- i_size);
+ i_hwKeyHash);
}
/**
* @brief Hash Signed Blob
*
*/
-errlHndl_t hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf)
+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);
@@ -297,10 +301,13 @@ errlHndl_t SecureROM::initialize()
/**
* @brief Verify Container against system hash keys
*/
-errlHndl_t SecureROM::verifyContainer(void * i_container, size_t i_size)
+errlHndl_t SecureROM::verifyContainer(void * i_container,
+// TODO securebootp9 - this is dummy parameter added to aid in p9 port
+// need to replace the method below with up-to-date version
+ const sha2_hash_t* i_hwKeyHash)
{
TRACDCOMP(g_trac_secure,ENTER_MRK"SecureROM::verifyContainer(): "
- "i_container=%p, size=0x%x", i_container, i_size);
+ "i_container=%p", i_container);
errlHndl_t l_errl = NULL;
@@ -410,7 +417,7 @@ errlHndl_t SecureROM::verifyContainer(void * i_container, size_t i_size)
/**
* @brief Hash Blob
*/
-errlHndl_t SecureROM::hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf)
+errlHndl_t SecureROM::hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf) const
{
TRACDCOMP(g_trac_secure,INFO_MRK"SecureROM::hashBlob() NOT "
diff --git a/src/usr/secureboot/base/securerom.H b/src/usr/secureboot/base/securerom.H
index cd5688cc4..bfb16f88b 100644
--- a/src/usr/secureboot/base/securerom.H
+++ b/src/usr/secureboot/base/securerom.H
@@ -139,11 +139,13 @@ class SecureROM
*
* @param[in] i_container Void pointer to effective address
* of container
- * @param[in] i_size Size of container
+ * @param[in] i_hwKeyHash Custom hw keys' hash to test against
+ * [default = nullptr, use current hw hash key
*
- * @return errlHndl_t NULL on success
+ * @return errlHndl_t NULL on success
*/
- errlHndl_t verifyContainer(void * i_container, size_t i_size);
+ errlHndl_t verifyContainer(void * i_container,
+ const sha2_hash_t* i_hwKeyHash = nullptr);
/**
* @brief Hash Blob
@@ -155,7 +157,7 @@ class SecureROM
*
* @return errlHndl_t NULL on success
*/
- errlHndl_t hashBlob(void * i_blob, size_t i_size, SHA512_t io_buf);
+ 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
diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C
index 435ababfd..ade0e4a9f 100644
--- a/src/usr/secureboot/base/service.C
+++ b/src/usr/secureboot/base/service.C
@@ -28,50 +28,98 @@
#include <util/singleton.H>
#include <secureboot/secure_reasoncodes.H>
#include <config.h>
-
+#include <devicefw/userif.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/targetservice.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <initservice/initserviceif.H>
#include "settings.H"
-#include "header.H"
+#include <secureboot/header.H>
#include "purge.H"
#include <kernel/misc.H>
+#include <kernel/console.H>
+#include <console/consoleif.H>
+
+extern trace_desc_t* g_trac_secure;
+
+// Quick change for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+
+using namespace ERRORLOG;
+using namespace TARGETING;
namespace SECUREBOOT
{
- void* initializeBase(void* unused)
+
+// TODO securebootp9 - Do a diff of this file with the p8 version make sure
+// all the missing parts are brought in.
+
+void* initializeBase(void* unused)
+{
+ errlHndl_t l_errl = NULL;
+
+ do
{
- errlHndl_t l_errl = NULL;
- do
+ // Load original secureboot header.
+ if (enabled())
{
+ Singleton<Header>::instance().loadBaseHeader();
+ }
- // Load original secureboot header.
- if (enabled())
- {
- Singleton<Header>::instance().loadBaseHeader();
- }
-
- // Extend memory footprint into lower portion of cache.
- assert(0 == mm_extend(MM_EXTEND_PARTIAL_CACHE));
+ // Extend memory footprint into lower portion of cache.
+ assert(0 == mm_extend(MM_EXTEND_PARTIAL_CACHE));
- // Don't extend more than 1/2 cache in VPO as fake PNOR is there
- // Don't enable SecureROM in VPO
+ // Don't extend more than 1/2 cache in VPO as fake PNOR is there
+ // Don't enable SecureROM in VPO
#ifndef CONFIG_P9_VPO_COMPILE
- // Run dcbz on the entire 10MB cache
- assert(0 == mm_extend(MM_EXTEND_FULL_CACHE));
-
- // Initialize the Secure ROM
- l_errl = initializeSecureROM();
- if (l_errl)
- {
- break;
- }
+ // Run dcbz on the entire 10MB cache
+ assert(0 == mm_extend(MM_EXTEND_FULL_CACHE));
+
+ // Initialize the Secure ROM
+ l_errl = initializeSecureROM();
+ if (l_errl)
+ {
+ break;
+ }
+#endif
+ } while(0);
+
+ return l_errl;
+}
+
+bool enabled()
+{
+ return Singleton<Settings>::instance().getEnabled();
+}
+
+void handleSecurebootFailure(errlHndl_t &i_err)
+{
+ TRACFCOMP( g_trac_secure, ENTER_MRK"handleSecurebootFailure()");
+
+ assert(i_err != NULL, "Secureboot Failure has a NULL error log")
+
+ // Grab errlog reason code before committing.
+ uint16_t l_rc = i_err->reasonCode();
+
+#ifdef CONFIG_CONSOLE
+ CONSOLE::displayf(SECURE_COMP_NAME, "Secureboot Failure plid = 0x%08X, rc = 0x%04X\n",
+ i_err->plid(), l_rc);
#endif
- } while(0);
+ printk("Secureboot Failure plid = 0x%08X, rc = 0x%04X\n",
+ i_err->plid(),l_rc);
- return l_errl;
- }
+ // Add Verification callout
+ i_err->addProcedureCallout(HWAS::EPUB_PRC_FW_VERIFICATION_ERR,
+ HWAS::SRCI_PRIORITY_HIGH);
+ errlCommit(i_err, SECURE_COMP_ID);
+
+ // Shutdown with Secureboot error status
+ INITSERVICE::doShutdown(l_rc);
+}
- bool enabled()
- {
- return Singleton<Settings>::instance().getEnabled();
- }
}
diff --git a/src/usr/secureboot/base/test/secureromtest.H b/src/usr/secureboot/base/test/secureromtest.H
index 9de9aaa80..d324de8cc 100644
--- a/src/usr/secureboot/base/test/secureromtest.H
+++ b/src/usr/secureboot/base/test/secureromtest.H
@@ -136,8 +136,7 @@ class SecureROMTest : public CxxTest::TestSuite
// Warn about the exception being handled during verification
printkd("test_verify(): expect to see 'mfsr r2 to CFAR handled': ");
- l_errl = l_sRom.verifyContainer( signedFile_pageAddr,
- signedFile_size );
+ l_errl = l_sRom.verifyContainer( signedFile_pageAddr);
if (l_errl)
{
diff --git a/src/usr/secureboot/header.H b/src/usr/secureboot/header.H
deleted file mode 100644
index a78f79b80..000000000
--- a/src/usr/secureboot/header.H
+++ /dev/null
@@ -1,53 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/secureboot/header.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
-/* */
-/* 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 __SECUREBOOT_HEADER_H
-#define __SECUREBOOT_HEADER_H
-
-#include <stdint.h>
-
-/** @file header.H
- *
- * @brief Classes for manipulating Secureboot headers.
- */
-
-namespace SECUREBOOT
-{
- /** @class Header
- * @brief Class for storing the original Secureboot header for later use.
- */
- class Header
- {
- public:
- Header() : iv_data(NULL) {};
- ~Header() {};
-
- /** @brief Extract header from original HRMOR - 1 page address. */
- void loadBaseHeader();
-
- private:
- /** Copy of the original secureboot header for the base image. */
- void* iv_data;
- };
-};
-
-#endif
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 687aeb9f0..dbb47b6e5 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -255,4 +255,27 @@ 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 l_errhdl = NULL;
+
+ // 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);
+
+ return l_errhdl;
+}
+
+errlHndl_t extendBaseImage()
+{
+ errlHndl_t pError = NULL;
+ // TODO securebootp9
+ // implement extendBaseImage based on p8 code
+ return pError;
+}
+
} // end TRUSTEDBOOT
OpenPOWER on IntegriCloud