summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2017-04-22 17:15:03 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-05-08 14:12:48 -0400
commit8527fc2b9549b9b6782fdffde29ff8713e677bc4 (patch)
treeeb277c60fcf28eec2116546c2ce4be6ca4a53144 /src
parentb93bb1c4e5151e309231a6b667bc98deaf98572f (diff)
downloadtalos-hostboot-8527fc2b9549b9b6782fdffde29ff8713e677bc4.tar.gz
talos-hostboot-8527fc2b9549b9b6782fdffde29ff8713e677bc4.zip
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 <smcprek@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build/buildpnor/buildpnor.pl10
-rw-r--r--src/build/buildpnor/defaultPnorLayout.xml2
-rwxr-xr-xsrc/build/buildpnor/genPnorImages.pl70
-rw-r--r--src/build/buildpnor/pnorLayoutFSP.xml1
-rw-r--r--src/include/usr/pnor/pnorif.H42
-rw-r--r--src/usr/pnor/pnor_common.C45
-rw-r--r--src/usr/pnor/pnor_utils.C24
-rw-r--r--src/usr/pnor/pnorrp.C31
-rw-r--r--src/usr/pnor/runtime/rt_pnor.C20
-rw-r--r--src/usr/pnor/runtime/rt_pnor.H17
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/xmltohb.pl4
11 files changed, 229 insertions, 37 deletions
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
<physicalOffset>0xF61000</physicalOffset>
<physicalRegionSize>0x48000</physicalRegionSize>
<sha512perEC/>
+ <sha512Version/>
<side>sideless</side>
<ecc/>
</section>
@@ -191,6 +192,7 @@ Layout Description
<eyeCatch>PAYLOAD</eyeCatch>
<physicalOffset>0x1549000</physicalOffset>
<physicalRegionSize>0x1560000</physicalRegionSize>
+ <sha512Version/>
<side>sideless</side>
<ecc/>
</section>
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
<physicalOffset>0xF61000</physicalOffset>
<physicalRegionSize>0x48000</physicalRegionSize>
<sha512perEC/>
+ <sha512Version/>
<side>sideless</side>
<ecc/>
</section>
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<SectionId>(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<PnorRP>::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<RtPnor>::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 =
OpenPOWER on IntegriCloud