From 8527fc2b9549b9b6782fdffde29ff8713e677bc4 Mon Sep 17 00:00:00 2001 From: Nick Bofferding Date: Sat, 22 Apr 2017 17:15:03 -0500 Subject: Support gracefully adding signing headers to PNOR sections Change-Id: Ie8ce7672a41c0b6230918911f59ada5443c552f5 RTC: 170650 CMVC-Coreq: 1022416 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39869 Reviewed-by: Stephen M. Cprek Tested-by: Jenkins Server Reviewed-by: Michael Baiocchi Tested-by: FSP CI Jenkins Tested-by: Jenkins OP Build CI Reviewed-by: Daniel M. Crowell --- src/build/buildpnor/buildpnor.pl | 10 +++-- src/build/buildpnor/defaultPnorLayout.xml | 2 + src/build/buildpnor/genPnorImages.pl | 70 ++++++++++++++++++----------- src/build/buildpnor/pnorLayoutFSP.xml | 1 + src/include/usr/pnor/pnorif.H | 42 +++++++++++++++++ src/usr/pnor/pnor_common.C | 45 +++++++++++++++++++ src/usr/pnor/pnor_utils.C | 24 +++++++++- src/usr/pnor/pnorrp.C | 31 +++++++++++++ src/usr/pnor/runtime/rt_pnor.C | 20 ++++++++- src/usr/pnor/runtime/rt_pnor.H | 17 ++++++- src/usr/targeting/common/xmltohb/xmltohb.pl | 4 +- 11 files changed, 229 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/build/buildpnor/buildpnor.pl b/src/build/buildpnor/buildpnor.pl index 3cfb5d67a..28930dc47 100755 --- a/src/build/buildpnor/buildpnor.pl +++ b/src/build/buildpnor/buildpnor.pl @@ -216,14 +216,16 @@ sub addUserData $dataInteg = 0x8000; } - # VerCheck Flag + # VerCheck Flag: sha512Version if( ($i_sectionHash{$i_key}{sha512Version} eq "yes") ) { - $verCheck = 0x80; + $verCheck |= 0x80; } - elsif( ($i_sectionHash{$i_key}{sha512perEC} eq "yes") ) + + # VerCheck Flag: sha512perEC + if( ($i_sectionHash{$i_key}{sha512perEC} eq "yes") ) { - $verCheck = 0x40; + $verCheck |= 0x40; } # Misc Flags diff --git a/src/build/buildpnor/defaultPnorLayout.xml b/src/build/buildpnor/defaultPnorLayout.xml index 54d4bc516..9bfbc6a47 100644 --- a/src/build/buildpnor/defaultPnorLayout.xml +++ b/src/build/buildpnor/defaultPnorLayout.xml @@ -165,6 +165,7 @@ Layout Description 0xF61000 0x48000 + sideless @@ -191,6 +192,7 @@ Layout Description PAYLOAD 0x1549000 0x1560000 + sideless diff --git a/src/build/buildpnor/genPnorImages.pl b/src/build/buildpnor/genPnorImages.pl index f02d0433b..dd0be0fce 100755 --- a/src/build/buildpnor/genPnorImages.pl +++ b/src/build/buildpnor/genPnorImages.pl @@ -617,7 +617,7 @@ sub manipulateImages $eccless_prefix.=".header"; # Add secure container header # @TODO RTC:155374 Remove when official signing supported - if ($secureboot && $secureSupported) + if ($secureboot && $isSpecialSecure) { $callerHwHdrFields{configure} = 1; if (exists $hashPageTablePartitions{$eyeCatch}) @@ -737,7 +737,25 @@ sub manipulateImages die "Error closing of $preReqImages{HBB_SW_SIG_FILE} failed" if $!; } } - # Add simiple version header + elsif($secureboot && $isNormalSecure) + { + $callerHwHdrFields{configure} = 1; + if($openSigningTool) + { + run_command("$CUR_OPEN_SIGN_REQUEST " + . "-protectedPayload $bin_file " + . "-out $tempImages{HDR_PHASE}"); + } + else + { + # @TODO RTC:155374 Remove when official signing + # supported + run_command("$SIGNING_DIR/build -good -if " + . "$secureboot_hdr -of $tempImages{HDR_PHASE} -bin " + . "$bin_file $SIGN_BUILD_PARAMS"); + } + } + # Add simple version header else { run_command("env echo -en VERSION\\\\0 > $tempImages{TEMP_SHA_IMG}"); @@ -746,23 +764,6 @@ sub manipulateImages run_command("cat $bin_file >> $tempImages{HDR_PHASE}"); } } - elsif ($secureboot && $isNormalSecure) - { - $eccless_prefix .=".header"; - - $callerHwHdrFields{configure} = 1; - if($openSigningTool) - { - run_command("$CUR_OPEN_SIGN_REQUEST " - . "-protectedPayload $bin_file " - . "-out $tempImages{HDR_PHASE}"); - } - else - { - # @TODO RTC:155374 Remove when official signing supported - run_command("$SIGNING_DIR/build -good -if $secureboot_hdr -of $tempImages{HDR_PHASE} -bin $bin_file $SIGN_BUILD_PARAMS"); - } - } else { run_command("cp $bin_file $tempImages{HDR_PHASE}"); @@ -830,17 +831,32 @@ sub manipulateImages run_command("dd if=/dev/zero bs=$size count=1 | tr \"\\000\" \"\\377\" > $tempImages{PAD_PHASE}"); # Add secure container header - if ($secureboot && $isNormalSecure && $eyeCatch ne "SBKT") + if( ($sectionHash{$layoutKey}{sha512Version} eq "yes") + && ($eyeCatch ne "SBKT")) { - $callerHwHdrFields{configure} = 1; - # Remove PAGE_SIZE bytes from generated dummy content of file - # to make room for the secure header + # Remove PAGE_SIZE bytes from generated dummy content of + # file to make room for the secure header my $fileSize = (-s $tempImages{PAD_PHASE}) - PAGE_SIZE; - die "fileSize undefined: errno = $!" unless(defined $fileSize); + die "fileSize undefined: errno = $!" + unless(defined $fileSize); run_command("dd if=$tempImages{PAD_PHASE} of=$tempImages{TEMP_BIN} count=1 bs=$fileSize"); - # @TODO RTC:155374 Remove when official signing supported - run_command("$SIGNING_DIR/build -good -if $secureboot_hdr -of $tempImages{PAD_PHASE} -bin $tempImages{TEMP_BIN} $SIGN_BUILD_PARAMS"); - setCallerHwHdrFields(\%callerHwHdrFields, $tempImages{PAD_PHASE}); + + if ($secureboot && $secureSupported) + { + $callerHwHdrFields{configure} = 1; + # @TODO RTC:155374 Remove when official signing + # supported + run_command("$SIGNING_DIR/build -good -if $secureboot_hdr -of $tempImages{PAD_PHASE} -bin $tempImages{TEMP_BIN} $SIGN_BUILD_PARAMS"); + setCallerHwHdrFields(\%callerHwHdrFields, + $tempImages{PAD_PHASE}); + } + else + { + run_command("env echo -en VERSION\\\\0 > $tempImages{TEMP_SHA_IMG}"); + run_command("sha512sum $tempImages{TEMP_BIN} | awk \'{print \$1}\' | xxd -pr -r >> $tempImages{TEMP_SHA_IMG}"); + run_command("dd if=$tempImages{TEMP_SHA_IMG} of=$tempImages{PAD_PHASE} ibs=4k conv=sync"); + run_command("cat $tempImages{TEMP_BIN} >> $tempImages{PAD_PHASE}"); + } } } } diff --git a/src/build/buildpnor/pnorLayoutFSP.xml b/src/build/buildpnor/pnorLayoutFSP.xml index f1b160c60..39fbe326c 100644 --- a/src/build/buildpnor/pnorLayoutFSP.xml +++ b/src/build/buildpnor/pnorLayoutFSP.xml @@ -165,6 +165,7 @@ Layout Description - Used when building an FSP driver 0xF61000 0x48000 + sideless diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H index e4c61c72e..3a2d3e53b 100644 --- a/src/include/usr/pnor/pnorif.H +++ b/src/include/usr/pnor/pnorif.H @@ -221,6 +221,48 @@ const char * SectionIdToString( uint32_t i_secIdIndex ); */ bool cmpSecurebootMagicNumber(const uint8_t* i_vaddr); +// @TODO RTC 173489 +// Remove API once FSP fully supports signing of PNOR sections that did not +// previously have a sha512 header +/** + * @brief Determines whether requested PNOR section has a recognized header + * + * @param[in] i_secId ID of requested section + * @param[in] i_TOC TOC entry for requested section + * @param[out] o_knownHeader Whether header was recognized or not + * + * @return errlHndl_t Error log handle + * @retval nullptr Success! Output parameter valid + * @retval !nullptr Error log pointer; output parameter invalid + */ +errlHndl_t hasKnownHeader( + PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + bool& o_knownHeader); + +// @TODO RTC 173489 +// Remove API once FSP fully supports signing of PNOR sections that did not +// previously have a sha512 header +/** + * @brief Read first few bytes of requested section's "potential" header + * + * @param[in] i_secId ID of requested section + * @param[in] i_TOC TOC entry for requested section + * @param[in] i_size Number of bytes to read from the beginning of the + * requested section + * @param[in] o_pData Pointer to a buffer of at least "i_size" bytes to + * hold the returned data. Asserts if nullptr + * + * @return errlHndl_t Error log handle + * @retval nullptr Success! Requested bytes read to output buffer + * @retval !nullptr Error log pointer; output buffer invalid + */ +errlHndl_t readHeaderMagic( + PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + size_t i_size, + void* o_pData); + } // PNOR #endif diff --git a/src/usr/pnor/pnor_common.C b/src/usr/pnor/pnor_common.C index b3bc54c35..5ae0eed30 100644 --- a/src/usr/pnor/pnor_common.C +++ b/src/usr/pnor/pnor_common.C @@ -430,3 +430,48 @@ errlHndl_t PNOR::setSecure(const uint32_t i_secId, return l_errhdl; } + +// @TODO RTC 173489 +// Remove API once FSP fully supports signing of PNOR sections that did not +// previously have a sha512 header +errlHndl_t PNOR::hasKnownHeader( + const PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + bool& o_knownHeader) +{ + errlHndl_t pError = nullptr; + bool knownHeader = true; + + do { + + // Left symbolic constant defined in the function so it's easier to strip + // out later and nothing becomes dependent on it + const char VERSION_MAGIC[] = "VERSION"; + const auto versionMagicSize = sizeof(VERSION_MAGIC); + const auto secureMagicSize = sizeof(ROM_MAGIC_NUMBER); + auto size = std::max(versionMagicSize,secureMagicSize); + assert(size <= sizeof(uint64_t),"non-ECC request size exceeded. " + "Expected size of <= %d but got %d",sizeof(uint64_t),size); + uint8_t buf[size] = {0}; + + pError = readHeaderMagic(i_secId,i_TOC,size,buf); + if(pError) + { + break; + } + + auto secureHeader = PNOR::cmpSecurebootMagicNumber(buf); + decltype(secureHeader) versionHeader = + (memcmp(buf,VERSION_MAGIC,versionMagicSize) == 0); + if(!secureHeader && !versionHeader) + { + knownHeader = false; + } + + o_knownHeader = knownHeader; + + } while (0); + + return pError; +} + diff --git a/src/usr/pnor/pnor_utils.C b/src/usr/pnor/pnor_utils.C index a5950bc20..0f484d77e 100644 --- a/src/usr/pnor/pnor_utils.C +++ b/src/usr/pnor/pnor_utils.C @@ -319,6 +319,28 @@ PNOR::parseEntries (ffs_hdr* i_ffs_hdr, ((io_TOC[secId].size * 8 ) / 9); } + // @TODO RTC 173489 + // Remove once FSP fully supports signing of PNOR sections that did + // not previously have a sha512 header. Until then, turn off the SHA512 + // bit if it doesn't match known header types +#ifndef BOOTLOADER + if(io_TOC[secId].version & FFS_VERS_SHA512) + { + bool hasKnownHeader = true; + l_errhdl = PNOR::hasKnownHeader(static_cast(secId), + io_TOC[secId],hasKnownHeader); + if(l_errhdl) + { + break; + } + + if(!hasKnownHeader) + { + io_TOC[secId].version &= ~FFS_VERS_SHA512; + } + } +#endif + #ifdef BOOTLOADER io_TOC[secId].secure = PNOR::isEnforcedSecureSection(secId); #elif !defined(__HOSTBOOT_RUNTIME) // runtime is handled by rt_pnor code @@ -454,6 +476,6 @@ bool PNOR::cmpSecurebootMagicNumber(const uint8_t* i_vaddr) bool PNOR::hasNonSecureHeader(const PNOR::SectionData_t& i_secInfo) { - return i_secInfo.version == FFS_VERS_SHA512 && + return (i_secInfo.version & FFS_VERS_SHA512) && !i_secInfo.secure; } diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 6d56efa8c..9a7e6baa4 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -149,6 +149,37 @@ errlHndl_t PNOR::fixECC(PNOR::SectionId i_section) return Singleton::instance().fixECC(i_section); } +// @TODO RTC 173489 +// Remove API once FSP fully supports signing of PNOR sections that did not +// previously have a sha512 header +errlHndl_t PNOR::readHeaderMagic( + const PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + const size_t i_size, + void* const o_pData) +{ + errlHndl_t pError = nullptr; + assert(o_pData != nullptr,"Output buffer pointer was nullptr"); + + do { + + size_t size = i_size; + auto pTarget = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + // Read first <=8 bytes of section data from the PNOR DD + // Note: Do not need to worry about ECC as the 9th byte is the first + // ECC byte. + pError = DeviceFW::deviceRead(pTarget, o_pData, size, + DEVICE_PNOR_ADDRESS(0,i_TOC.flashAddr)); + if (pError) + { + break; + } + + } while(0); + + return pError; +} + /** * STATIC * @brief Static Initializer diff --git a/src/usr/pnor/runtime/rt_pnor.C b/src/usr/pnor/runtime/rt_pnor.C index a614ae274..d4f5f8400 100644 --- a/src/usr/pnor/runtime/rt_pnor.C +++ b/src/usr/pnor/runtime/rt_pnor.C @@ -86,6 +86,24 @@ errlHndl_t PNOR::clearSection(PNOR::SectionId i_section) return Singleton::instance().clearSection(i_section); } +// @TODO RTC 173489 +// Remove API once FSP fully supports signing of PNOR sections that did not +// previously have a sha512 header +errlHndl_t PNOR::readHeaderMagic( + const PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + const size_t i_size, + void* const o_pData) +{ + errlHndl_t pError = RtPnor::readFromDevice (RtPnor::iv_masterProcId, + i_secId, + 0, + i_size, + false, + o_pData); + return pError; +} + void PNOR::getPnorInfo( PnorInfo_t& o_pnorInfo ) { o_pnorInfo.mmioOffset = LPC_SFC_MMIO_OFFSET | LPC_FW_SPACE; @@ -365,7 +383,7 @@ errlHndl_t RtPnor::readFromDevice (uint64_t i_procId, uint64_t i_offset, size_t i_size, bool i_ecc, - void* o_data) const + void* o_data) { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readFromDevice: i_offset=0x%X, " "i_procId=%d sec=%d size=0x%X ecc=%d", i_offset, i_procId, i_section, diff --git a/src/usr/pnor/runtime/rt_pnor.H b/src/usr/pnor/runtime/rt_pnor.H index 61ec8a02f..b49aa3aaf 100644 --- a/src/usr/pnor/runtime/rt_pnor.H +++ b/src/usr/pnor/runtime/rt_pnor.H @@ -129,12 +129,25 @@ class RtPnor * * @return Error from device */ - errlHndl_t readFromDevice (uint64_t i_procId, + // @TODO RTC 173489 + // Remove static once FSP fully supports signing of PNOR sections that + // did not previously have a sha512 header. Also add the const method + // qualifier back in + static errlHndl_t readFromDevice (uint64_t i_procId, PNOR::SectionId i_section, uint64_t i_offset, size_t i_size, bool i_ecc, - void* o_data) const; + void* o_data); + + // @TODO RTC 173489 + // Remove API once FSP fully supports signing of PNOR sections that did + // not previously have a sha512 header + friend errlHndl_t PNOR::readHeaderMagic( + PNOR::SectionId i_secId, + const PNOR::SectionData_t& i_TOC, + size_t i_size, + void* const o_pData); /** * @brief Write data back to the PNOR device diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index a05196b84..0ca61f5e9 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -6138,8 +6138,8 @@ sub generateTargetingImage { $md5hex->add($associationsBinData); $md5hex->add($heapPnorInitBinData); - my $versionHeader = "VERSION"; - my $versionHeader .= $md5hex->hexdigest; + my $versionHeader = "VERSION\0"; + $versionHeader .= $md5hex->hexdigest; $outFile .= $versionHeader; my $versionHeaderPadSize = -- cgit v1.2.1