diff options
author | Stephen Cprek <smcprek@us.ibm.com> | 2017-01-27 12:05:45 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-03-10 13:44:11 -0500 |
commit | 6f2f153d6b5132a5604ce068be8ac8cf4cb7b14e (patch) | |
tree | 7d1fb2ddbfdf9b83e235534a6f31600effcc1a32 | |
parent | 41cfdf72da59cc35815c34698ae201b777ecae7c (diff) | |
download | talos-hostboot-6f2f153d6b5132a5604ce068be8ac8cf4cb7b14e.tar.gz talos-hostboot-6f2f153d6b5132a5604ce068be8ac8cf4cb7b14e.zip |
Relocate ROM code after HBBL has been verified
Create Bootloader to hostboot data manager to control how
the shared data is accessed and modified.
Change-Id: I54cb543ed289810ab6afb07d333313f5662bce0e
RTC: 166848
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35617
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/HBconfig | 5 | ||||
-rw-r--r-- | src/include/bootloader/bootloaderif.H | 4 | ||||
-rw-r--r-- | src/include/kernel/bltohbdatamgr.H | 164 | ||||
-rw-r--r-- | src/include/kernel/vmmmgr.H | 4 | ||||
-rw-r--r-- | src/include/usr/secureboot/service.H | 8 | ||||
-rw-r--r-- | src/kernel/bltohbdatamgr.C | 211 | ||||
-rw-r--r-- | src/kernel/kernel.C | 55 | ||||
-rw-r--r-- | src/kernel/makefile | 4 | ||||
-rw-r--r-- | src/kernel/pagemgr.C | 22 | ||||
-rw-r--r-- | src/makefile | 3 | ||||
-rw-r--r-- | src/usr/secureboot/base/securerommgr.C | 435 | ||||
-rw-r--r-- | src/usr/secureboot/base/securerommgr.H | 73 | ||||
-rw-r--r-- | src/usr/secureboot/base/test/securerommgrtest.H | 107 |
13 files changed, 695 insertions, 400 deletions
diff --git a/src/HBconfig b/src/HBconfig index 05093085f..f45ae2a2f 100644 --- a/src/HBconfig +++ b/src/HBconfig @@ -29,11 +29,6 @@ config P9_PAGE_TABLE help Use the P9 version of the page table setup -config ROM_CODE_PRESENT - default n - help - Indicates that ROM code is available to call - config INCLUDE_XML_OPPOWERVM default y help diff --git a/src/include/bootloader/bootloaderif.H b/src/include/bootloader/bootloaderif.H index 47b011542..eb157a348 100644 --- a/src/include/bootloader/bootloaderif.H +++ b/src/include/bootloader/bootloaderif.H @@ -69,7 +69,7 @@ struct BlToHbData branchtableOffset(0), secureRom(nullptr), secureRomSize(0), hwKeysHash(nullptr), hwKeysHashSize(0), hbbHeader(nullptr), - hbbHeaderSize(0), totalSize(0) {} + hbbHeaderSize(0) {} // Simple way to tell if data is valid uint64_t eyeCatch; @@ -89,8 +89,6 @@ struct BlToHbData const void* hbbHeader; // size of Hostboot base header size_t hbbHeaderSize; - // Total size of data preserved by the Kernel - size_t totalSize; } __attribute__((packed)); /** diff --git a/src/include/kernel/bltohbdatamgr.H b/src/include/kernel/bltohbdatamgr.H new file mode 100644 index 000000000..49f5db525 --- /dev/null +++ b/src/include/kernel/bltohbdatamgr.H @@ -0,0 +1,164 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/kernel/bltohbdatamgr.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] 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 __BLTOHBDATAMANAGER_H +#define __BLTOHBDATAMANAGER_H + +#include <stdint.h> +#include <sys/mm.h> +#include <bootloader/bootloaderif.H> + +// BlToHbDataManager class +class BlToHbDataManager +{ + private: + + /** + * @brief Performs a printk along with a kassert to be more verbose if + * Data is not valid. + * + * @return N/A + */ + void validAssert() const; + + /* + * @brief Prints, via printkd, important parts of the structure + * + * @return N/A + */ + void print() const; + + // Data received from the bootloader + static Bootloader::BlToHbData iv_data; + // Indicates if the class has been instantiated or not + static bool iv_instantiated; + // Indicates if the class has been initialized or not + static bool iv_initialized; + // Indicates if data received from the bootloader is valid + static bool iv_dataValid; + // Size of data that needs to be preserved and pinned. + static size_t iv_preservedSize; + // Converts secureROM pointer to a 64-bit address + const uint64_t getSecureRomAddr() const; + // Converts hw keys hash pointer to a 64-bit address + const uint64_t getHwKeysHashAddr() const; + // Converts HBB header pointer to a 64-bit address + const uint64_t getHbbHeaderAddr() const; + + public: + + /** + * @brief Default Constructor + */ + BlToHbDataManager(); + + /** + * @brief Initializes all internal data. At the time this class is + * instantiated the data is not known, so created this function + * as a type of "pseudo" constructor for the class. + * + * @param[in] i_data Bootloader to Hostboot Data to initialize the + * internal data with. + * + * @return N/A + */ + void initValid (const Bootloader::BlToHbData& i_data); + + /** + * @brief Sets internal members to indicate that the class has been + * initialized, but is invalid + * + * @return N/A + */ + void initInvalid(); + + /* + * @brief Returns internal branchtable offset + * + * @return uint64_t branchtable offset + */ + const uint64_t getBranchtableOffset() const; + + /* + * @brief Returns internal pointer to secureROM + * + * @return void* pointer to secureROM + */ + const void* getSecureRom() const; + + /* + * @brief Returns internal secureRomSize + * + * @return size_t secureRomSize + */ + const size_t getSecureRomSize() const; + + /* + * @brief Returns internal pointer to hwKeysHash + * + * @return void* pointer to hwKeysHash + */ + const void* getHwKeysHash() const; + + /* + * @brief Returns internal hwKeysHashSize + * + * @return size_t hwKeysHashSize + */ + const size_t getHwKeysHashSize() const; + + /* + * @brief Returns internal pointer to hbbHeader + * + * @return void* pointer to hbbHeader + */ + const void* getHbbHeader() const; + + /* + * @brief Returns internal hbbHeaderSize + * + * @return size_t hbbHeaderSize + */ + const size_t getHbbHeaderSize() const; + + /* + * @brief Returns internal preserved size + * + * @return size_t preserved size + */ + const size_t getPreservedSize() const; + + /* + * @brief Indicates if internal data is valid or not + * + * @return bool true if valid; false otherwise + */ + const bool isValid() const; +}; + +// Extern global instance of the class +extern BlToHbDataManager g_BlToHbDataManager; + +#endif
\ No newline at end of file diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H index 78c15cdbf..84a981b24 100644 --- a/src/include/kernel/vmmmgr.H +++ b/src/include/kernel/vmmmgr.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2010,2016 */ +/* Contributors Listed Below - COPYRIGHT 2010,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -60,6 +60,8 @@ class VmmManager FIRST_RESERVED_PAGE = INITIAL_PT_OFFSET, END_RESERVED_PAGE = INITIAL_PT_OFFSET + PTSIZE + MBOX_DMA_SIZE, + BLTOHB_DATA_START = END_RESERVED_PAGE, + // Tells processor to ignore HRMOR FORCE_PHYS_ADDR = 0x8000000000000000, }; diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H index 538148061..73b254fd8 100644 --- a/src/include/usr/secureboot/service.H +++ b/src/include/usr/secureboot/service.H @@ -186,9 +186,9 @@ namespace SECUREBOOT * @param[in] i_size Size of blob in bytes * @param[out] o_hash SHA512 hash * - * @return errlHndl_t NULL on success + * @return N/A */ - errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf); + void hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf); /** * @brief Retrieve the internal hardware keys' hash used to validate @@ -208,9 +208,9 @@ namespace SECUREBOOT * of the blob to concatenate * @param[out] o_buf SHA512 hash * - * @return errlHndl_t NULL on success + * @return N/A */ - errlHndl_t hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf); + void hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf); /** * @brief Common secureboot handler for secureboot failures. diff --git a/src/kernel/bltohbdatamgr.C b/src/kernel/bltohbdatamgr.C new file mode 100644 index 000000000..f165ae87b --- /dev/null +++ b/src/kernel/bltohbdatamgr.C @@ -0,0 +1,211 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/kernel/bltohbdatamgr.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] 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 <kernel/bltohbdatamgr.H> +#include <util/align.H> +#include <kernel/console.H> +#include <assert.h> + +// Global and only BlToHbDataManager instance +BlToHbDataManager g_BlToHbDataManager; + +//////////////////////////////////////////////////////////////////////////////// +//--------------------------------- Private ----------------------------------// +//////////////////////////////////////////////////////////////////////////////// + +// Set static variables to control use +Bootloader::BlToHbData BlToHbDataManager::iv_data; +bool BlToHbDataManager::iv_instantiated = false; +bool BlToHbDataManager::iv_initialized = false; +bool BlToHbDataManager::iv_dataValid = false; +size_t BlToHbDataManager::iv_preservedSize = 0; + +void BlToHbDataManager::validAssert() const +{ + if(!iv_dataValid) + { + printk("E> BlToHbDataManager is invalid, cannot access\n"); + kassert(iv_dataValid); + } +} + +void BlToHbDataManager::print() const +{ + if(iv_dataValid) + { + printkd("\nBlToHbData (all addr HRMOR relative):\n"); + printkd("-- eyeCatch = 0x%lX (%s)\n", iv_data.eyeCatch, + reinterpret_cast<char*>(&iv_data.eyeCatch)); + printkd("-- version = 0x%lX\n", iv_data.version); + printkd("-- branchtableOffset = 0x%lX\n", iv_data.branchtableOffset); + printkd("-- SecureRom Addr = 0x%lX Size = 0x%lX\n", getSecureRomAddr(), + iv_data.secureRomSize); + printkd("-- HW keys' Hash Addr = 0x%lX Size = 0x%lX\n", getHwKeysHashAddr(), + iv_data.hwKeysHashSize); + printkd("-- HBB header Addr = 0x%lX Size = 0x%lX\n", getHbbHeaderAddr(), + iv_data.hbbHeaderSize); + printkd("-- Reserved Size = 0x%lX\n", iv_preservedSize); + printkd("\n"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//---------------------------------- Public ----------------------------------// +//////////////////////////////////////////////////////////////////////////////// + +BlToHbDataManager::BlToHbDataManager() +{ + // Allow only one instantiation + if (iv_instantiated) + { + printk("E> A BlToHbDataManager class instance already exists\n"); + kassert(!iv_instantiated); + } + iv_instantiated = true; +} + +void BlToHbDataManager::initValid (const Bootloader::BlToHbData& i_data) +{ + // Allow only one initializer call + if (iv_initialized) + { + printk("E> BlToHbDataManager class previously initialized\n"); + kassert(!iv_initialized); + } + + // Simple assertion checks + kassert(i_data.eyeCatch>0); + kassert(i_data.version>0); + kassert(i_data.branchtableOffset>0); + kassert(i_data.secureRom!=nullptr); + kassert(i_data.hwKeysHash!=nullptr); + kassert(i_data.hbbHeader!=nullptr); + kassert(i_data.secureRomSize>0); + kassert(i_data.hwKeysHashSize>0); + kassert(i_data.hbbHeaderSize>0); + + // Set internal static data + iv_data.eyeCatch = i_data.eyeCatch; + iv_data.version = i_data.version; + iv_data.branchtableOffset = i_data.branchtableOffset; + iv_data.secureRom = i_data.secureRom; + iv_data.secureRomSize = i_data.secureRomSize; + iv_data.hwKeysHash = i_data.hwKeysHash; + iv_data.hwKeysHashSize = i_data.hwKeysHashSize; + iv_data.hbbHeader = i_data.hbbHeader; + iv_data.hbbHeaderSize = i_data.hbbHeaderSize; + + // Size of data that needs to be preserved and pinned. + iv_preservedSize = ALIGN_PAGE(iv_data.secureRomSize + + iv_data.hwKeysHashSize + + iv_data.hbbHeaderSize ); + iv_initialized = true; + iv_dataValid = true; + print(); +} + +void BlToHbDataManager::initInvalid () +{ + // Allow only one initializer call + if (iv_initialized) + { + printk("E> BlToHbDataManager class previously initialized\n"); + kassert(!iv_initialized); + } + + iv_initialized = true; + iv_dataValid = false; + print(); +} + +const uint64_t BlToHbDataManager::getBranchtableOffset() const +{ + validAssert(); + return iv_data.branchtableOffset; +} + +const void* BlToHbDataManager::getSecureRom() const +{ + validAssert(); + return iv_data.secureRom; +} + +const uint64_t BlToHbDataManager::getSecureRomAddr() const +{ + validAssert(); + return reinterpret_cast<uint64_t>(iv_data.secureRom); +} + +const size_t BlToHbDataManager::getSecureRomSize() const +{ + validAssert(); + return iv_data.secureRomSize; +} + +const void* BlToHbDataManager::getHwKeysHash() const +{ + validAssert(); + return iv_data.hwKeysHash; +} + +const uint64_t BlToHbDataManager::getHwKeysHashAddr() const +{ + validAssert(); + return reinterpret_cast<uint64_t>(iv_data.hwKeysHash); +} + +const size_t BlToHbDataManager::getHwKeysHashSize() const +{ + validAssert(); + return iv_data.hwKeysHashSize; +} + +const void* BlToHbDataManager::getHbbHeader() const +{ + validAssert(); + return iv_data.hbbHeader; +} + +const uint64_t BlToHbDataManager::getHbbHeaderAddr() const +{ + validAssert(); + return reinterpret_cast<uint64_t>(iv_data.hbbHeader); +} + +const size_t BlToHbDataManager::getHbbHeaderSize() const +{ + validAssert(); + return iv_data.hbbHeaderSize; +} + +const size_t BlToHbDataManager::getPreservedSize() const +{ + validAssert(); + return iv_preservedSize; +} + +const bool BlToHbDataManager::isValid() const +{ + return iv_dataValid; +}
\ No newline at end of file diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C index 8ae092458..f470723ce 100644 --- a/src/kernel/kernel.C +++ b/src/kernel/kernel.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2014 */ +/* Contributors Listed Below - COPYRIGHT 2010,2017 */ +/* [+] 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. */ @@ -35,6 +37,9 @@ #include <sys/vfs.h> #include <kernel/deferred.H> #include <kernel/misc.H> +#include <util/align.H> +#include <securerom/sha512.H> +#include <kernel/bltohbdatamgr.H> #include <stdlib.h> @@ -64,6 +69,54 @@ int main() Kernel& kernel = Singleton<Kernel>::instance(); kernel.cppBootstrap(); + + // Get pointer to BL and HB comm data + const auto l_pBltoHbData = reinterpret_cast<const Bootloader::BlToHbData*>( + BLTOHB_COMM_DATA_ADDR); + + if ( Bootloader::BlToHbDataValid(l_pBltoHbData) ) + { + printk("Valid BL to HB communication data\n"); + + // Make copy of structure so to not modify original pointers + auto l_blToHbDataCopy = *l_pBltoHbData; + + // Get destination location that will be preserved by the pagemgr + auto l_pBltoHbDataStart = reinterpret_cast<uint8_t *>( + VmmManager::BLTOHB_DATA_START); + // Copy in SecureRom + memcpy(l_pBltoHbDataStart, + l_blToHbDataCopy.secureRom, + l_blToHbDataCopy.secureRomSize); + // Change pointer to new location and increment + l_blToHbDataCopy.secureRom = l_pBltoHbDataStart; + l_pBltoHbDataStart += l_blToHbDataCopy.secureRomSize; + + // Copy in HW keys' Hash + memcpy(l_pBltoHbDataStart, + l_blToHbDataCopy.hwKeysHash, + l_blToHbDataCopy.hwKeysHashSize); + // Change pointer to new location and increment + l_blToHbDataCopy.hwKeysHash = l_pBltoHbDataStart; + l_pBltoHbDataStart += l_blToHbDataCopy.hwKeysHashSize; + + // Copy in HBB header + memcpy(l_pBltoHbDataStart, + l_blToHbDataCopy.hbbHeader, + l_blToHbDataCopy.hbbHeaderSize); + // Change pointer to new location + l_blToHbDataCopy.hbbHeader = l_pBltoHbDataStart; + + // Initialize Secureboot Data class + g_BlToHbDataManager.initValid(l_blToHbDataCopy); + } + else + { + printk("Invalid BL to HB communication data\n"); + // Force invalidation of securebootdata + g_BlToHbDataManager.initInvalid(); + } + kernel.memBootstrap(); kernel.cpuBootstrap(); diff --git a/src/kernel/makefile b/src/kernel/makefile index cf5a69aa7..ddf3909ab 100644 --- a/src/kernel/makefile +++ b/src/kernel/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2010,2016 +# Contributors Listed Below - COPYRIGHT 2010,2017 # [+] International Business Machines Corp. # # @@ -67,5 +67,7 @@ OBJS += machchk.o OBJS += doorbell.o OBJS += workitem.o +OBJS += bltohbdatamgr.o + include ${ROOTPATH}/config.mk diff --git a/src/kernel/pagemgr.C b/src/kernel/pagemgr.C index c5e7d6960..66f62e6da 100644 --- a/src/kernel/pagemgr.C +++ b/src/kernel/pagemgr.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2010,2015 */ +/* Contributors Listed Below - COPYRIGHT 2010,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -36,6 +36,7 @@ #include <sys/syscall.h> #include <assert.h> #include <kernel/memstate.H> +#include <kernel/bltohbdatamgr.H> size_t PageManager::cv_coalesce_count = 0; @@ -208,6 +209,15 @@ void PageManager::_initialize() page_t* endAddr = reinterpret_cast<page_t*>(VmmManager::INITIAL_MEM_SIZE); printk("Initializing PageManager starting at %p...", startAddr); + // Add on secureboot data size to end of reserved space + size_t securebootDataSize = 0; + if (g_BlToHbDataManager.isValid()) + { + securebootDataSize = g_BlToHbDataManager.getPreservedSize(); + } + size_t l_endReservedPage = VmmManager::END_RESERVED_PAGE + + securebootDataSize; + // Calculate chunks along the top half of the L3 and erase them. uint64_t currentBlock = reinterpret_cast<uint64_t>(startAddr); do @@ -225,17 +235,17 @@ void PageManager::_initialize() // Check if this block starts in the hole. if ((currentBlock >= VmmManager::FIRST_RESERVED_PAGE) && - (currentBlock < VmmManager::END_RESERVED_PAGE)) + (currentBlock < l_endReservedPage)) { // End of the block is in the hole, skip. - if (endBlock < VmmManager::END_RESERVED_PAGE) + if (endBlock < l_endReservedPage) { currentBlock = ALIGN_MEGABYTE(endBlock); continue; } // Advance the current block past the hole. - currentBlock = VmmManager::END_RESERVED_PAGE; + currentBlock = l_endReservedPage; } // Check if the block is has the hole in it. @@ -243,7 +253,7 @@ void PageManager::_initialize() (currentBlock < VmmManager::FIRST_RESERVED_PAGE)) { // Hole is at the end of the block, shrink it down. - if (endBlock < VmmManager::END_RESERVED_PAGE) + if (endBlock < l_endReservedPage) { endBlock = VmmManager::FIRST_RESERVED_PAGE; } @@ -262,7 +272,7 @@ void PageManager::_initialize() iv_heap.addMemory(currentBlock, hole_end / PAGESIZE); totalPages += (hole_end / PAGESIZE); - currentBlock = VmmManager::END_RESERVED_PAGE; + currentBlock = l_endReservedPage; } } diff --git a/src/makefile b/src/makefile index de74f6420..fdb6713fe 100644 --- a/src/makefile +++ b/src/makefile @@ -133,6 +133,7 @@ DIRECT_BOOT_OBJECTS += cpuid.o DIRECT_BOOT_OBJECTS += stdlib.o DIRECT_BOOT_OBJECTS += assert.o DIRECT_BOOT_OBJECTS += workitem.o +DIRECT_BOOT_OBJECTS += bltohbdatamgr.o BASE_MODULES += trace BASE_MODULES += errl @@ -212,7 +213,7 @@ TESTCASE_MODULES += testpnor TESTCASE_MODULES += testvfs TESTCASE_MODULES += testutil TESTCASE_MODULES += testscan -TESTCASE_MODULES += $(if $(CONFIG_ROM_CODE_PRESENT),testsecureboot) +TESTCASE_MODULES += testsecureboot TESTCASE_MODULES += testfsiscom TESTCASE_MODULES += testlpc TESTCASE_MODULES += $(if $(CONFIG_HTMGT),testhtmgt) diff --git a/src/usr/secureboot/base/securerommgr.C b/src/usr/secureboot/base/securerommgr.C index b79640d0d..4f92b3d14 100644 --- a/src/usr/secureboot/base/securerommgr.C +++ b/src/usr/secureboot/base/securerommgr.C @@ -33,25 +33,20 @@ #include <errl/errlentry.H> #include <errl/errlmanager.H> #include "../common/securetrace.H" +#include <kernel/bltohbdatamgr.H> #include "securerommgr.H" #include <secureboot/settings.H> +#include <config.h> +#include <console/consoleif.H> // Quick change for unit testing //#define TRACUCOMP(args...) TRACFCOMP(args) #define TRACUCOMP(args...) - -// Hardcode define for Secure ROM code (bootrom.bin) in system -// Secure ROM has 16KB reserved address space -#define SECUREROM_MEMORY_SIZE (16 * KILOBYTE) -// 4 pages * (PAGESIZE=4K) = 16K -#define SECUREROM_NUM_PAGES (SECUREROM_MEMORY_SIZE / PAGESIZE) - namespace SECUREBOOT { - /** * @brief Initialize Secure Rom by loading it into memory and * retrieving Hash Keys @@ -61,40 +56,49 @@ errlHndl_t initializeSecureRomManager(void) return Singleton<SecureRomManager>::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, const sha2_hash_t* i_hwKeyHash) { - TRACUCOMP(g_trac_secure, "verifyContainer(): i_container=%p, size=0x%x", - i_container, i_size); + errlHndl_t l_errl = nullptr; + + // @TODO RTC:170136 remove isValid check + if(Singleton<SecureRomManager>::instance().isValid()) + { + l_errl = Singleton<SecureRomManager>::instance(). + verifyContainer(i_container,i_hwKeyHash); + } - return Singleton<SecureRomManager>::instance().verifyContainer(i_container, - i_hwKeyHash); + return l_errl; } /** * @brief Hash Signed Blob * */ -errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf) +void hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf) { - return Singleton<SecureRomManager>::instance().hashBlob(i_blob, i_size, - io_buf); + // @TODO RTC:170136 remove isValid check + if(Singleton<SecureRomManager>::instance().isValid()) + { + return Singleton<SecureRomManager>::instance(). + hashBlob(i_blob, i_size, o_buf); + } } /** * @brief Hash concatenation of 2 Blobs * */ -errlHndl_t hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf) +void hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf) { - return Singleton<SecureRomManager>::instance().hashConcatBlobs(i_blobs, - o_buf); + // @TODO RTC:170136 remove isValid check + if(Singleton<SecureRomManager>::instance().isValid()) + { + return Singleton<SecureRomManager>::instance(). + hashConcatBlobs(i_blobs, o_buf); + } } /* @@ -102,7 +106,11 @@ errlHndl_t hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf) */ void getHwKeyHash(sha2_hash_t o_hash) { - return Singleton<SecureRomManager>::instance().getHwKeyHash(o_hash); + // @TODO RTC:170136 remove isValid check + if(Singleton<SecureRomManager>::instance().isValid()) + { + return Singleton<SecureRomManager>::instance().getHwKeyHash(o_hash); + } } }; //end SECUREBOOT namespace @@ -122,131 +130,73 @@ errlHndl_t SecureRomManager::initialize() { TRACDCOMP(g_trac_secure,ENTER_MRK"SecureRomManager::initialize()"); - errlHndl_t l_errl = NULL; -#if (0) - bool l_cleanup = false; + errlHndl_t l_errl = nullptr; uint32_t l_rc = 0; do{ - - // Check to see if ROM has already been initialized - if (iv_device_ptr != NULL) + // @TODO RTC:170136 terminate in initialize if the securebit is on + // and code is not valid. Remove all isValid() checks in rest of + // SecureRomManager. + // Check if secureboot data is valid. + iv_secureromValid = g_BlToHbDataManager.isValid(); + if (!iv_secureromValid) { // The Secure ROM has already been initialized - TRACUCOMP(g_trac_secure,"SecureRomManager::initialize(): Already " - "Loaded: iv_device_ptr=%p", iv_device_ptr); + TRACFCOMP(g_trac_secure,"SecureRomManager::initialize(): SecureROM invalid, skipping functionality"); - // Can skip the rest of this function - break; - } - - - /*********************************************************************/ - /* Find base address of Secure ROM via TBROM_BASE_REG scom register */ - /*********************************************************************/ - - const uint32_t tbrom_reg_addr = 0x02020017; - uint64_t tbrom_reg_data; - size_t op_size = sizeof(uint64_t); - - l_errl = deviceRead( TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, - &(tbrom_reg_data), - op_size, - DEVICE_SCOM_ADDRESS(tbrom_reg_addr) ); - - if (l_errl != NULL) - { - TRACFCOMP(g_trac_secure,ERR_MRK"SecureRomManager::initialize():" - " Fail SCOM Read of tbrom_reg_addr (0x%x)", tbrom_reg_addr); +#ifdef CONFIG_CONSOLE + CONSOLE::displayf(SECURE_COMP_NAME, "SecureROM invalid - skipping functionality"); +#endif + // Can skip the rest of this function break; } + TRACFCOMP(g_trac_secure,"SecureRomManager::initialize(): SecureROM valid, enabling functionality"); +#ifdef CONFIG_CONSOLE + CONSOLE::displayf(SECURE_COMP_NAME, "SecureROM valid - enabling functionality"); +#endif - TRACUCOMP(g_trac_secure,INFO_MRK"SecureRomManager::initialize(): " - "tbrom_reg_data = 0x%016llx", tbrom_reg_data); - - - // This register contains the starting address of the bootrom device - void * l_rom_baseAddr = reinterpret_cast<void*>(tbrom_reg_data); - - - /*******************************************************************/ - /* Map the bootrom code into virtual memory */ - /*******************************************************************/ - void * l_rom_virtAddr = mmio_dev_map(l_rom_baseAddr, THIRTYTWO_GB); - - if (l_rom_virtAddr == NULL) + // Check to see if ROM has already been initialized + if (iv_securerom != nullptr) { - TRACFCOMP(g_trac_secure,ERR_MRK"SecureRomManager::initialize():" - " mmio_dev_map failed: l_rom_virtAddr=%p, l_rom_baseAddr=%p", - l_rom_virtAddr, l_rom_baseAddr); - - /*@ - * @errortype - * @moduleid SECUREBOOT::MOD_SECURE_ROM_INIT - * @reasoncode SECUREBOOT::RC_DEV_MAP_FAIL - * @userdata1 TBROM Register Address - * @userdata2 TBROM Register Data - * @devdesc mmio_dev_map() failed for Secure ROM - * @custdesc A problem occurred during the IPL of the system. - */ - l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - SECUREBOOT::MOD_SECURE_ROM_INIT, - SECUREBOOT::RC_DEV_MAP_FAIL, - TO_UINT64(tbrom_reg_addr), - tbrom_reg_data, - true /*Add HB Software Callout*/ ); + // The Secure ROM has already been initialized + TRACUCOMP(g_trac_secure,"SecureRomManager::initialize(): Already " + "Loaded: iv_securerom=%p", iv_securerom); - l_errl->collectTrace(SECURE_COMP_NAME,256); + // Can skip the rest of this function break; - } - /**********************************************************************/ - /* Allocate Memory: Request full SECUREROM_MEMORY_SIZE */ - /**********************************************************************/ - - // Using malloc() rather than allocatePage because malloc() will - // handle error path - iv_device_ptr = malloc(SECUREROM_MEMORY_SIZE); - - // Pages are now allocated, so free below if necessary - l_cleanup = true; - - /***************************************************************/ - /* Copy and setup ROM code in allocated memory */ - /***************************************************************/ - - // memcpy from mapped device to allocated pages - memcpy( iv_device_ptr, l_rom_virtAddr, SECUREROM_MEMORY_SIZE ); + // ROM code starts at the end of the reserved page + iv_securerom = g_BlToHbDataManager.getSecureRom(); // invalidate icache to make sure that bootrom code in memory is used - size_t l_icache_invalid_size = (SECUREROM_MEMORY_SIZE / + size_t l_icache_invalid_size = (g_BlToHbDataManager.getPreservedSize() / sizeof(uint64_t)); - mm_icache_invalidate( iv_device_ptr, l_icache_invalid_size); + mm_icache_invalidate(const_cast<void*>(iv_securerom), + l_icache_invalid_size); // Make this address space executable uint64_t l_access_type = EXECUTABLE; - l_rc = mm_set_permission( iv_device_ptr, - SECUREROM_MEMORY_SIZE, + l_rc = mm_set_permission( const_cast<void*>(iv_securerom), + g_BlToHbDataManager.getPreservedSize(), l_access_type); - if (l_rc != 0) { TRACFCOMP(g_trac_secure,EXIT_MRK"SecureRomManager::initialize():" " Fail from mm_set_permission(EXECUTABLE): l_rc=0x%x, ptr=%p, " - "size=0x%x, access=0x%x", l_rc, iv_device_ptr, - SECUREROM_MEMORY_SIZE, l_access_type); + "size=0x%x, access=0x%x", l_rc, iv_securerom, + g_BlToHbDataManager.getPreservedSize(), EXECUTABLE); /*@ * @errortype * @moduleid SECUREBOOT::MOD_SECURE_ROM_INIT * @reasoncode SECUREBOOT::RC_SET_PERMISSION_FAIL_EXE * @userdata1 l_rc - * @userdata2 iv_device_ptr + * @userdata2 iv_securerom * @devdesc mm_set_permission(EXECUTABLE) failed for Secure ROM * @custdesc A problem occurred during the IPL of the system. */ @@ -255,7 +205,7 @@ errlHndl_t SecureRomManager::initialize() SECUREBOOT::MOD_SECURE_ROM_INIT, SECUREBOOT::RC_SET_PERMISSION_FAIL_EXE, TO_UINT64(l_rc), - reinterpret_cast<uint64_t>(iv_device_ptr), + reinterpret_cast<uint64_t>(iv_securerom), true /*Add HB Software Callout*/ ); l_errl->collectTrace(SECURE_COMP_NAME,256); @@ -263,72 +213,49 @@ errlHndl_t SecureRomManager::initialize() } - /***************************************************************/ /* Retrieve HW Hash Keys From The System */ /***************************************************************/ - // @todo RTC:RTC:34080 - Support for SecureRomManager::getHwKeyHash() - l_errl = SecureRomManager::getHwKeyHash(); - - if (l_errl != NULL) - { - TRACFCOMP(g_trac_secure,ERR_MRK"SecureRomManager::initialize():" - " SecureRomManager::getHwKeyHash() returned an error"); + SecureRomManager::getHwKeyHash(); - l_errl->collectTrace(SECURE_COMP_NAME,256); - break; - - } - - - /***************************************************************/ - /* Secure ROM successfully initialized */ - /***************************************************************/ - // If we've made it this far without an error, than Secure ROM - // is properly initialized and pages shouldn't be de-allocated - l_cleanup = false; TRACFCOMP(g_trac_secure,INFO_MRK"SecureRomManager::initialize(): SUCCESSFUL:" - " iv_device_ptr=%p", iv_device_ptr); - + " iv_securerom=%p", iv_securerom); }while(0); - // Check to see if we should free pages - if (l_cleanup == true) - { - SecureRomManager::_cleanup(); - } - TRACDCOMP(g_trac_secure,EXIT_MRK"SecureRomManager::initialize() - %s", - ((NULL == l_errl) ? "No Error" : "With Error") ); -#endif - return l_errl; + ((nullptr == l_errl) ? "No Error" : "With Error") ); + return l_errl; } - /** * @brief Verify Container against system hash keys */ errlHndl_t SecureRomManager::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"SecureRomManager::verifyContainer(): " "i_container=%p", i_container); - errlHndl_t l_errl = NULL; + errlHndl_t l_errl = nullptr; uint64_t l_rc = 0; do{ + // Check if secureboot data is valid. + if (!iv_secureromValid) + { + // Can skip the rest of this function + break; + } + // Check to see if ROM has already been initialized // This should have been done early in IPL so assert if this // is not the case as system is in a bad state - assert(iv_device_ptr != NULL); + assert(iv_securerom != nullptr); // Declare local input struct @@ -341,24 +268,34 @@ errlHndl_t SecureRomManager::verifyContainer(void * i_container, // Now set hw_key_hash, which is of type sha2_hash_t, to iv_key_hash memcpy (&l_hw_parms.hw_key_hash, &iv_key_hash, sizeof(sha2_hash_t)); + if (i_hwKeyHash == nullptr) + { + // Use current hw hash key + memcpy (&l_hw_parms.hw_key_hash, &iv_key_hash, sizeof(sha2_hash_t)); + } + else + { + // Use custom hw hash key + memcpy (&l_hw_parms.hw_key_hash, i_hwKeyHash, sizeof(sha2_hash_t)); + } + /*******************************************************************/ /* Call ROM_verify() function via an assembly call */ /*******************************************************************/ // Set startAddr to ROM_verify() function at an offset of Secure ROM - uint64_t l_rom_verify_startAddr = reinterpret_cast<uint64_t>( - iv_device_ptr) - + ROM_VERIFY_FUNCTION_OFFSET; + uint64_t l_rom_verify_startAddr = + reinterpret_cast<uint64_t>(iv_securerom) + + g_BlToHbDataManager.getBranchtableOffset() + + ROM_VERIFY_FUNCTION_OFFSET; TRACUCOMP(g_trac_secure,"SecureRomManager::verifyContainer(): " " Calling ROM_verify() via call_rom_verify: l_rc=0x%x, " "l_hw_parms.log=0x%x (&l_hw_parms=%p) addr=%p (iv_d_p=%p)", l_rc, l_hw_parms.log, &l_hw_parms, l_rom_verify_startAddr, - iv_device_ptr); - + iv_securerom); ROM_container_raw* l_container = reinterpret_cast<ROM_container_raw*>(i_container); - l_rc = call_rom_verify(reinterpret_cast<void*> (l_rom_verify_startAddr), l_container, @@ -369,7 +306,7 @@ errlHndl_t SecureRomManager::verifyContainer(void * i_container, "Back from ROM_verify() via call_rom_verify: l_rc=0x%x, " "l_hw_parms.log=0x%x (&l_hw_parms=%p) addr=%p (iv_d_p=%p)", l_rc, l_hw_parms.log, &l_hw_parms, l_rom_verify_startAddr, - iv_device_ptr); + iv_securerom); @@ -378,7 +315,7 @@ errlHndl_t SecureRomManager::verifyContainer(void * i_container, TRACFCOMP(g_trac_secure,ERR_MRK"SecureRomManager::verifyContainer():" " ROM_verify() FAIL: l_rc=0x%x, l_hw_parms.log=0x%x " "addr=%p (iv_d_p=%p)", l_rc, l_hw_parms.log, - l_rom_verify_startAddr, iv_device_ptr); + l_rom_verify_startAddr, iv_securerom); /*@ * @errortype @@ -408,7 +345,7 @@ errlHndl_t SecureRomManager::verifyContainer(void * i_container, TRACDCOMP(g_trac_secure,EXIT_MRK"SecureRomManager::verifyContainer() - %s", - ((NULL == l_errl) ? "No Error" : "With Error") ); + ((nullptr == l_errl) ? "No Error" : "With Error") ); return l_errl; } @@ -417,66 +354,66 @@ errlHndl_t SecureRomManager::verifyContainer(void * i_container, /** * @brief Hash Blob */ -errlHndl_t SecureRomManager::hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf) const +void SecureRomManager::hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf) const { - TRACDCOMP(g_trac_secure,INFO_MRK"SecureRomManager::hashBlob() NOT " - "supported, but not returning error log"); - - errlHndl_t l_errl = NULL; - - do{ -#ifdef CONFIG_ROM_CODE_PRESENT + TRACDCOMP(g_trac_secure,INFO_MRK"SecureRomManager::hashBlob()"); + // Check if secureboot data is valid. + if (iv_secureromValid) + { // Check to see if ROM has already been initialized // This should have been done early in IPL so assert if this // is not the case as system is in a bad state - assert(iv_device_ptr != NULL); + assert(iv_securerom != nullptr); // Set startAddr to ROM_SHA512() function at an offset of Secure ROM - uint64_t l_rom_SHA512_startAddr = reinterpret_cast<uint64_t>( - iv_device_ptr) - + SHA512_HASH_FUNCTION_OFFSET; + uint64_t l_rom_SHA512_startAddr = + reinterpret_cast<uint64_t>(iv_securerom) + + g_BlToHbDataManager.getBranchtableOffset() + + SHA512_HASH_FUNCTION_OFFSET; call_rom_SHA512(reinterpret_cast<void*>(l_rom_SHA512_startAddr), - reinterpret_cast<sha2_byte*>(i_blob), + reinterpret_cast<const sha2_byte*>(i_blob), i_size, - reinterpret_cast<sha2_hash_t*>(io_buf)); + reinterpret_cast<sha2_hash_t*>(o_buf)); TRACUCOMP(g_trac_secure,"SecureRomManager::hashBlob(): " "call_rom_SHA512: blob=%p size=0x%X addr=%p (iv_d_p=%p)", i_blob, i_size, l_rom_SHA512_startAddr, - iv_device_ptr); -#endif - }while(0); - + iv_securerom); + } TRACDCOMP(g_trac_secure,EXIT_MRK"SecureRomManager::hashBlob()"); - - return l_errl; } /** * @brief Hash concatenation of N Blobs */ -errlHndl_t SecureRomManager::hashConcatBlobs(const blobPair_t &i_blobs, +void SecureRomManager::hashConcatBlobs(const blobPair_t &i_blobs, SHA512_t o_buf) const { - errlHndl_t pError = nullptr; - std::vector<uint8_t> concatBuf; - for (const auto &it : i_blobs) + // Check if secureboot data is valid. + if (iv_secureromValid) { - assert(it.first != nullptr, "BUG! In SecureRomManager::hashConcatBlobs(), " - "User passed in nullptr blob pointer"); - const uint8_t* const blob = static_cast<const uint8_t*>(it.first); - const auto blobSize = it.second; - concatBuf.insert(concatBuf.end(), blob, blob + blobSize); - } + std::vector<uint8_t> concatBuf; + for (const auto &it : i_blobs) + { + assert(it.first != nullptr, "BUG! In SecureRomManager::hashConcatBlobs(), " + "User passed in nullptr blob pointer"); + const uint8_t* const blob = static_cast<const uint8_t*>(it.first); + const auto blobSize = it.second; + concatBuf.insert(concatBuf.end(), blob, blob + blobSize); + } - // Call hash blob on new concatenated buffer - pError = hashBlob(concatBuf.data(),concatBuf.size(),o_buf); + // Call hash blob on new concatenated buffer + hashBlob(concatBuf.data(),concatBuf.size(),o_buf); + } +} - return pError; +bool SecureRomManager::isValid() +{ + return iv_secureromValid; } /******************** @@ -484,118 +421,26 @@ errlHndl_t SecureRomManager::hashConcatBlobs(const blobPair_t &i_blobs, ********************/ /** - * @brief Constructor + * @brief Retrieves HW Keys from the system */ -SecureRomManager::SecureRomManager() -:iv_device_ptr(NULL) +void SecureRomManager::getHwKeyHash() { - TRACDCOMP(g_trac_secure, "SecureRomManager::SecureRomManager()>"); - - // Clear out iv_key_hash, which is of type sha2_hash_t - memset(&iv_key_hash, 0, sizeof(sha2_hash_t) ); - -} - -/** - * @brief Destructor - */ -SecureRomManager::~SecureRomManager() { SecureRomManager::_cleanup(); }; - -void SecureRomManager::_cleanup() -{ - // deallocate pages - if ( iv_device_ptr != NULL ) + // Check if secureboot data is valid. + if (iv_secureromValid) { - - // Make this address space writable before sending it back - // to the Page Manager via free, otherwise PM will crash trying to - // update the previously-defined-as-excutable memory space - uint64_t l_access_type = WRITABLE; - uint64_t l_rc = mm_set_permission( iv_device_ptr, - SECUREROM_MEMORY_SIZE, - l_access_type ); - - if (l_rc != 0) - { - TRACFCOMP(g_trac_secure,ERR_MRK"SecureRomManager:::_cleanup():" - " Fail from mm_set_permission(WRITABLE): l_rc=0x%x, ptr=%p, " - "size=0x%x, pages=%d, access=0x%x", l_rc, iv_device_ptr, - SECUREROM_MEMORY_SIZE, SECUREROM_NUM_PAGES, l_access_type); - - /*@ - * @errortype - * @moduleid SECUREBOOT::MOD_SECURE_ROM_CLEANUP - * @reasoncode SECUREBOOT::RC_SET_PERMISSION_FAIL_WRITE - * @userdata1 l_rc - * @userdata2 iv_device_ptr - * @devdesc mm_set_permission(WRITABLE) failed for Secure ROM - * @custdesc A problem occurred during the IPL of the system. - */ - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - SECUREBOOT::MOD_SECURE_ROM_CLEANUP, - SECUREBOOT::RC_SET_PERMISSION_FAIL_WRITE, - TO_UINT64(l_rc), - reinterpret_cast<uint64_t>(iv_device_ptr), - true /*Add HB Software Callout*/ ); - - l_errl->collectTrace(SECURE_COMP_NAME,256); - - // Commit here because function doesn't return error handle - errlCommit(l_errl, SECURE_COMP_ID); - - // NOTE: Purposely not calling free() here - - // prefer to have a memory leak than have another task crash - // due to pages still being excutable or in a bad state - - } - else - { - // Safe to free allocated pages - free(iv_device_ptr); - - TRACDCOMP(g_trac_secure,INFO_MRK - "SecureRomManager::_cleanup(): pages set to " - "WRITABLE (rc=0x%x) and free called", l_rc); - - - // Reset device ptr - iv_device_ptr = NULL; - } - + iv_key_hash = reinterpret_cast<const sha2_hash_t*>( + g_BlToHbDataManager.getHwKeysHash()); } } - -/** - * @brief Retrieves HW keys' hash from the system - */ -errlHndl_t SecureRomManager::getHwKeyHash() -{ - - errlHndl_t l_errl = NULL; - - TRACFCOMP(g_trac_secure,INFO_MRK"SecureRomManager::getHwKeyHash() NOT supported"); - - // @todo RTC:34080 - Add support for getting HW keys' hash from System - - return l_errl; -} - /** * @brief Retrieve the internal hardware keys' hash from secure ROM object. */ void SecureRomManager::getHwKeyHash(sha2_hash_t o_hash) { - memcpy(o_hash, iv_key_hash, sizeof(sha2_hash_t)); -} - -/** - * @brief Static instance function for testcase only - */ -SecureRomManager& SecureRomManager::getInstance() -{ - return Singleton<SecureRomManager>::instance(); + // Check if secureboot data is valid. + if (iv_secureromValid) + { + memcpy(o_hash, iv_key_hash, sizeof(sha2_hash_t)); + } } - - diff --git a/src/usr/secureboot/base/securerommgr.H b/src/usr/secureboot/base/securerommgr.H index 7ccbf9d77..3cbd0fc77 100644 --- a/src/usr/secureboot/base/securerommgr.H +++ b/src/usr/secureboot/base/securerommgr.H @@ -23,14 +23,17 @@ /* */ /* IBM_PROLOG_END_TAG */ -#ifndef __SECUREBOOT_SECUREROM_H -#define __SECUREBOOT_SECUREROM_H +#ifndef __SECUREBOOT_SECUREROMMANAGER_H +#define __SECUREBOOT_SECUREROMMANAGER_H #include <errl/errlentry.H> #include <securerom/ROM.H> +#include <utility> + +typedef std::vector< std::pair<void*,size_t> > blobPair_t; /** @class SecureRomManager - * @brief Class for loading and interacting with SecureRomManager in memory + * @brief Class for loading and interacting with SecureROM in memory */ class SecureRomManager { @@ -64,11 +67,11 @@ class SecureRomManager * @param[in] i_blob Void pointer to effective address * of blob * @param[in] i_size Size of blob in bytes - * @param[in/out] io_buf Resulting hash buffer + * @param[out] o_buf Resulting hash buffer * - * @return errlHndl_t NULL on success + * @return N/A */ - errlHndl_t hashBlob(const void * i_blob, size_t i_size, SHA512_t io_buf) const; + void hashBlob(const void * i_blob, size_t i_size, SHA512_t o_buf) const; /** * @brief Retrieve the internal hardware keys' hash from secure ROM @@ -89,22 +92,30 @@ class SecureRomManager * of the blob to concatenate * @param[out] o_buf SHA512 hash * - * @return errlHndl_t NULL on success + * @return N/A + */ + void hashConcatBlobs (const blobPair_t &i_blobs, SHA512_t o_buf) const; + + /* + * @brief Getter for private "is valid" variable + * + * @return bool - True if valid, false otherwise */ - errlHndl_t hashConcatBlobs (const blobPair_t &i_blobs, - SHA512_t o_buf) const; + bool isValid(); protected: /** - * @brief Constructor + * @brief Constructor */ - SecureRomManager(); + SecureRomManager():iv_securerom(nullptr), + iv_secureromValid(false), + iv_key_hash(nullptr) {} /** * @brief Destructor */ - ~SecureRomManager(); + ~SecureRomManager() {} private: @@ -113,15 +124,19 @@ class SecureRomManager ********************************************/ /** - * Void pointer to effective address location of Secure ROM - * in memory + * Void pointer to effective address location of Secure ROM in memory */ - void * iv_device_ptr; + const void * iv_securerom; + + /** + * Cached valid check if secure rom is valid + */ + bool iv_secureromValid; /** * HW key' hash retrieved from system */ - sha2_hash_t iv_key_hash; + const sha2_hash_t* iv_key_hash; /******************************************** * Private Functions @@ -129,33 +144,9 @@ class SecureRomManager /** * @brief Retrieves HW keys' hash from the system - * - * @return errlHndl_t NULL on success */ - errlHndl_t getHwKeyHash(); - - /** - * @brief Static instance function for testcase only - */ - static SecureRomManager& getInstance(); - - - /** - * @brief Safely Frees Allocated Memory - */ - void _cleanup(); - - - /******************************************** - * Friend(s) - ********************************************/ - - // let my testcase poke around - friend class SecureRomManagerTest; - + void getHwKeyHash(); }; // end of SecureRomManager class - - #endif diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H index 9372e1ad3..4ef0db2a6 100644 --- a/src/usr/secureboot/base/test/securerommgrtest.H +++ b/src/usr/secureboot/base/test/securerommgrtest.H @@ -22,8 +22,8 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -#ifndef __SECUREROMTEST_H -#define __SECURETOMTEST_H +#ifndef __SECUREROMMANAGERTEST_H +#define __SECUREROMMANAGERTEST_H #include <sys/mm.h> @@ -34,6 +34,7 @@ #include <errl/errlmanager.H> #include <secureboot/service.H> #include <secureboot/secure_reasoncodes.H> +#include <kernel/bltohbdatamgr.H> #include "../securerommgr.H" @@ -54,27 +55,27 @@ using namespace SECUREBOOT; // Moves signed files from PNOR to paged-in memory errlHndl_t loadSignedFile( const char * i_signedFile_name, void * & o_signedFile_pageAddr, - size_t & o_signedFile_size ); + size_t & o_signedFile_size, + uint64_t & o_signedFile_virtAddr); // Safely removes signed files from memory void unloadSignedFile( void * & io_signedFile_pageAddr, size_t & io_signedFile_size ); // secureboot_signed_container was generated using this hw hash key. If another -// key is in pibmem, this test will always fail. -const uint64_t hw_key_hash[] = +// key is in the HBBL, this test will always fail. +const sha2_hash_t hw_key_hash = { - 0x40d487ff7380ed6a, - 0xd54775d5795fea0d, - 0xe2f541fea9db06b8, - 0x466a42a320e65f75, - 0xb48665460017d907, - 0x515dc2a5f9fc5095, - 0x4d6ee0c9b67d219d, - 0xfb7085351d01d6d1 + 0x40,0xd4,0x87,0xff,0x73,0x80,0xed,0x6a, + 0xd5,0x47,0x75,0xd5,0x79,0x5f,0xea,0x0d, + 0xe2,0xf5,0x41,0xfe,0xa9,0xdb,0x06,0xb8, + 0x46,0x6a,0x42,0xa3,0x20,0xe6,0x5f,0x75, + 0xb4,0x86,0x65,0x46,0x00,0x17,0xd9,0x07, + 0x51,0x5d,0xc2,0xa5,0xf9,0xfc,0x50,0x95, + 0x4d,0x6e,0xe0,0xc9,0xb6,0x7d,0x21,0x9d, + 0xfb,0x70,0x85,0x35,0x1d,0x01,0xd6,0xd1 }; - /**********************************************************************/ /* End of UTILITY FUNCTIONS */ /**********************************************************************/ @@ -88,7 +89,7 @@ class SecureRomManagerTest : public CxxTest::TestSuite */ void test_verify(void) { - TRACFCOMP(g_trac_secure,ENTER_MRK"SecureRomManagerTest::test_verify>"); + TRACUCOMP(g_trac_secure,ENTER_MRK"SecureRomManagerTest::test_verify>"); errlHndl_t l_errl = NULL; @@ -100,12 +101,13 @@ class SecureRomManagerTest : public CxxTest::TestSuite const char * signedFile_name = "secureboot_signed_container"; void * signedFile_pageAddr = NULL; size_t signedFile_size = 0; + uint64_t signedFile_vaddr = 0; // Call utility function l_errl = loadSignedFile( signedFile_name, signedFile_pageAddr, - signedFile_size); - + signedFile_size, + signedFile_vaddr); if (l_errl) { TS_FAIL("SecureRomManagerTest::test_verify: loadSignedFile() Failed"); @@ -113,25 +115,6 @@ class SecureRomManagerTest : public CxxTest::TestSuite return; } - TRACUCOMP(g_trac_secure, "SecureRomManagerTest::test_verify: " - "signedFile info: addr = %p, size=0x%x", - signedFile_pageAddr, signedFile_size); - - SecureRomManager l_sRom; - - // Call initializeSecureRomManager() - l_errl = l_sRom.initialize(); - - if (l_errl) - { - TS_FAIL("SecureRomManagerTest::test_verify: initializeSecureRomManager() Failed"); - errlCommit(l_errl, SECURE_COMP_ID); - return; - } - - // Set hardware keys' hash - memcpy (& l_sRom.iv_key_hash, &hw_key_hash, sizeof(sha2_hash_t)); - /*******************************************************************/ /* Call verify function */ /*******************************************************************/ @@ -139,8 +122,8 @@ class SecureRomManagerTest : 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); - + l_errl = SECUREBOOT::verifyContainer(signedFile_pageAddr, + &hw_key_hash); if (l_errl) { TS_FAIL("SecureRomManagerTest::test_verify: verifyContainer() Failed"); @@ -149,15 +132,51 @@ class SecureRomManagerTest : public CxxTest::TestSuite } /*******************************************************************/ - /* Unload "secureboot_signed_container" from memory */ + /* Unload "secureboot_signed_container" from memory */ /*******************************************************************/ if ( signedFile_pageAddr != NULL ) { unloadSignedFile( signedFile_pageAddr, signedFile_size); } - TRACFCOMP(g_trac_secure,EXIT_MRK"SecureRomManagerTest::test_verify"); - }; + TRACUCOMP(g_trac_secure,EXIT_MRK"SecureRomManagerTest::test_verify"); + } + + /** + * @brief Secure ROM Test - Test sha512 hash + */ + void test_sha512(void) + { + TRACUCOMP(g_trac_secure,ENTER_MRK"SecureRomManagerTest::test_sha512>"); + + // Constants for sha512 test + const sha2_byte l_text[]={"The quick brown fox jumps over the lazy dog"}; + // Do not include NULL character in sha512 test + size_t l_textSize = 43; + const uint64_t l_textHash[] = + { + 0x07E547D9586F6A73, + 0xF73FBAC0435ED769, + 0x51218FB7D0C8D788, + 0xA309D785436BBB64, + 0x2E93A252A954F239, + 0x12547D1E8A3B5ED6, + 0xE1BFD7097821233F, + 0xA0538F3DB854FEE6 + }; + + // Result hash + SHA512_t l_resultHash = {0}; + SECUREBOOT::hashBlob(&l_text, l_textSize, l_resultHash); + + // Ensure calculated result matches expected result + if (memcmp(l_textHash, l_resultHash, SHA512_DIGEST_LENGTH) != 0) + { + TS_FAIL("SecureRomManagerTest::test_sha512: hashBlob() Failed"); + } + + TRACUCOMP(g_trac_secure,EXIT_MRK"SecureRomManagerTest::test_sha512"); + } }; /**********************************************************************/ @@ -167,7 +186,8 @@ class SecureRomManagerTest : public CxxTest::TestSuite // Moved secureboot_signed_container from PNOR to paged-in memory errlHndl_t loadSignedFile( const char * i_signedFile_name, void * & o_signedFile_pageAddr, - size_t & o_signedFile_size ) + size_t & o_signedFile_size, + uint64_t & o_signedFile_virtAddr) { errlHndl_t l_errl = NULL; @@ -199,6 +219,9 @@ errlHndl_t loadSignedFile( const char * i_signedFile_name, return l_errl; } + // Get the VFS virtual address + o_signedFile_virtAddr = reinterpret_cast<uint64_t>(l_signedFile_virtAddr); + // Request contiguous memory block to copy in file size_t l_num_pages = ALIGN_PAGE(o_signedFile_size)/PAGESIZE; bool l_isUserspace = true; |