diff options
author | Jaymes Wilks <mjwilks@us.ibm.com> | 2016-10-17 12:15:40 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-11-14 17:17:33 -0500 |
commit | 16263a641c48773091dd60b55e28ad77ca5a8574 (patch) | |
tree | 97120f76deb4132a1a1b7ceba8701318c5663a68 /src/include | |
parent | a904e156364a8f0fd5f6bc2b7094f79cf77da1b2 (diff) | |
download | talos-hostboot-16263a641c48773091dd60b55e28ad77ca5a8574.tar.gz talos-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/include')
-rw-r--r-- | src/include/usr/pnor/pnor_const.H | 8 | ||||
-rw-r--r-- | src/include/usr/pnor/pnor_reasoncodes.H | 16 | ||||
-rw-r--r-- | src/include/usr/pnor/pnorif.H | 43 | ||||
-rw-r--r-- | src/include/usr/secureboot/containerheader.H | 242 | ||||
-rw-r--r-- | src/include/usr/secureboot/header.H | 144 | ||||
-rw-r--r-- | src/include/usr/secureboot/rom.H | 195 | ||||
-rw-r--r-- | src/include/usr/secureboot/service.H | 31 | ||||
-rw-r--r-- | src/include/usr/secureboot/trustedbootif.H | 28 | ||||
-rw-r--r-- | src/include/usr/vmmconst.h | 18 |
9 files changed, 718 insertions, 7 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 }; /** |