diff options
-rw-r--r-- | src/include/usr/secureboot/header.H | 56 | ||||
-rw-r--r-- | src/usr/pnor/pnor_common.C | 33 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 5 | ||||
-rw-r--r-- | src/usr/secureboot/base/header.C | 57 |
4 files changed, 74 insertions, 77 deletions
diff --git a/src/include/usr/secureboot/header.H b/src/include/usr/secureboot/header.H index 4ad1f0e7e..34300ba9a 100644 --- a/src/include/usr/secureboot/header.H +++ b/src/include/usr/secureboot/header.H @@ -55,7 +55,7 @@ namespace SECUREBOOT */ ~Header() { - free(iv_data); + free(const_cast<void*>(iv_data)); iv_data=NULL; } @@ -64,8 +64,9 @@ namespace SECUREBOOT /** * @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. + * security area preserved across the bootloader to HBB + * handoff to support extending HBB measurements to TPM in + * secure mode. * * @warning Asserts if header is already cached (code bug) */ @@ -82,11 +83,7 @@ namespace SECUREBOOT * @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 + * @warning Carries all the same warnings as _set */ void setNonSecurely( const void* i_pHeader); @@ -95,16 +92,20 @@ namespace SECUREBOOT * @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. + * During boot, SBE copies the boot loader (HBBL) into the cache + * and hands off control to it. The boot loader then loads the + * base image (HBB), including its secure header. After + * verifying HBB, the boot loader copies hostboot to the trusted + * memory location and passes control to HBB, which locates and + * preserves the secure header (among other things) before + * initializing the other non-preserved areas of the cache. In + * secure mode, HBB then initializes this header object with the + * preserved secure header. + * + * In non-secure mode, Hostboot pulls the header from PNOR and + * and writes it into this object. + * + * This API then returns the addresses of the cached header. * * @param[out] o_pHeader Pointer to HBB header * @@ -116,17 +117,22 @@ namespace SECUREBOOT private: /** - * @brief Returns base (HBB) image secure load address (the address - * where SBE -always- loads hostboot regardless of security - * state) + * @brief Populate the base image (HBB) header (ECC removed) + * to support extending HBB measurements to TPM * - * @param[out] o_pCode Base (HBB) image secure load address + * @param[in] i_pHeader Pointer to 4k HBB header + * + * @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 _calcSecureLoadAddr( - const void*& o_pCode) const; + void _set( + const void* i_pHeader); // Pointer to copy of the base image's (HBB's) secureboot header - void* iv_data; + const void* iv_data; // Don't allow copies / assignments Header(const Header& that); diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C index 2414a15c2..93978c277 100644 --- a/src/usr/pnor/pnor_common.C +++ b/src/usr/pnor/pnor_common.C @@ -304,21 +304,26 @@ errlHndl_t PNOR::parseTOC( uint8_t* i_tocBuffer,SectionData_t * o_TOC) if ( o_TOC[l_secId].version == FFS_VERS_SHA512 && !isSecure) { - // For non-secure sections with a SHA512 header, the - // flash address has incremented past the header, so - // back up by the header size (accounting for ECC) in order - // to extend the header - auto addr = o_TOC[l_secId].flashAddr; - size_t headerSize = - (o_TOC[l_secId].integrity == FFS_INTEG_ECC_PROTECT) ? - PAGESIZE_PLUS_ECC : PAGESIZE; - addr -= headerSize; - - l_errhdl = PNOR::extendHash(addr, headerSize, - cv_EYECATCHER[l_secId]); - if (l_errhdl) + // Never extend the base image through this path, it will be + // handled elsewhere + if(l_secId != PNOR::HB_BASE_CODE) { - break; + // For non-secure sections with a SHA512 header, the + // flash address has incremented past the header, so + // back up by the header size (accounting for ECC) in order + // to extend the header + auto addr = o_TOC[l_secId].flashAddr; + size_t headerSize = + (o_TOC[l_secId].integrity == FFS_INTEG_ECC_PROTECT) ? + PAGESIZE_PLUS_ECC : PAGESIZE; + addr -= headerSize; + + l_errhdl = PNOR::extendHash(addr, headerSize, + cv_EYECATCHER[l_secId]); + if (l_errhdl) + { + break; + } } } } diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 6bca58f25..b3f394e51 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -337,10 +337,7 @@ void PnorRP::initDaemon() // runtime code. #ifndef __HOSTBOOT_RUNTIME #ifdef CONFIG_SECUREBOOT - //TODO: RTC 167581 - // When RTC 166848 is available, add restrictions back in when - // base image header copy availability is detected - // if(!SECUREBOOT::enabled()) + if(!SECUREBOOT::enabled()) { // If compliant bootloader was present, it saved the HBB header // to a known location accessible to HBB. Until that bootloader diff --git a/src/usr/secureboot/base/header.C b/src/usr/secureboot/base/header.C index 4aba9481f..2f62f804c 100644 --- a/src/usr/secureboot/base/header.C +++ b/src/usr/secureboot/base/header.C @@ -27,6 +27,7 @@ #include <sys/mmio.h> #include <kernel/console.H> #include <errno.h> +#include <kernel/bltohbdatamgr.H> namespace SECUREBOOT { @@ -39,10 +40,13 @@ namespace SECUREBOOT // header void Header::loadSecurely() { - //@TODO RTC 167581 - // When RTC 166848 is available, pull in real header + const void* const pSecureHeader = g_BlToHbDataManager.getHbbHeader(); - return; + // Fatal code bug if called with nullptr pointer + assert(pSecureHeader != nullptr, + "BUG! In Header::loadSecurely(), expected valid address for base " + "image header in secure mode, but got nullptr."); + _set(pSecureHeader); } // @TODO RTC 168021 Converge on a single method of reading the secure @@ -50,16 +54,27 @@ namespace SECUREBOOT void Header::setNonSecurely( const void* const i_pHeader) { + // Fatal code bug if called with nullptr pointer + assert(i_pHeader != nullptr,"BUG! In Header::setNonSecurely(), " + "caller passed a nullptr header address."); + _set(i_pHeader); + } + + void Header::_set( + const void* const i_pHeader) + { // Fatal code bug if already loaded - assert(iv_data == nullptr,"BUG! In setNonSecurely(), " + assert(iv_data == nullptr,"BUG! In Header::_set(), " "a cached header is already present."); // Fatal code bug if called with nullptr pointer - assert(i_pHeader != nullptr,"BUG! In setNonSecurely(), " - "caller passed a nullptr header."); + assert(i_pHeader != nullptr,"BUG! In Header::_set(), " + "caller passed a nullptr header address."); - iv_data = calloc(1,PAGESIZE); - memcpy(iv_data,i_pHeader,PAGE_SIZE); + void* pData = malloc(PAGESIZE); + memcpy(pData,i_pHeader,PAGE_SIZE); + iv_data = pData; + pData = nullptr; } void Header::getHeader( @@ -70,30 +85,4 @@ namespace SECUREBOOT "header is not present."); o_pHeader = iv_data; } - - void Header::_calcSecureLoadAddr( - const void*& o_pCode) const - { - //@TODO RTC 167581 - // When RTC 166848 is available, pull in real header - - // Determine the secure address where the HBB image was loaded by SBE. - // Regardless of whether security is enabled or not, HBB always ends up - // at the secure load address (which corresponds to the HRMOR). - // - // Zero is purposefully not mapped into the VMM tables, so we - // can't use that for the virtual-to-real translation. Since - // this object is in the base (HBB) image, PA = HRMOR | EA, so we can - // use PA - EA to find the HRMOR. - const void* hrmor = reinterpret_cast<const void*>( - mm_virt_to_phys( - const_cast<SECUREBOOT::Header*>(this)) - - reinterpret_cast<uint64_t>(this)); - - // HRMOR lookup should never fail - assert( reinterpret_cast<uint64_t>(hrmor) - != static_cast<uint64_t>(-EFAULT)); - - o_pCode = hrmor; - } } |