summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Du <duchen@us.ibm.com>2019-03-04 10:56:19 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-05-09 16:10:29 -0500
commitbbbd68a140c9b34ccded9273d91e6b5bc97d0f28 (patch)
tree930afab97b728563743d597510fe3e473bd998b3
parent6aeba3917d4d42f6b99a059eeacc57c850dca6b9 (diff)
downloadblackbird-hostboot-bbbd68a140c9b34ccded9273d91e6b5bc97d0f28.tar.gz
blackbird-hostboot-bbbd68a140c9b34ccded9273d91e6b5bc97d0f28.zip
Add page tables to read only partitions
Changed partitions (WOFDATA, MEMD) to be signed with a hash page table bit. This generates a hash page table in the protected payload which will be used to validate pages in the unprotected payload Change-Id: I9be4b1f6e65b9a52a8b6ba23affdacc4d89f5295 RTC: 179519 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72776 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rwxr-xr-xsrc/build/buildpnor/genPnorImages.pl19
-rw-r--r--src/include/securerom/ROM.H8
-rw-r--r--src/include/usr/pnor/pnor_const.H4
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H7
-rw-r--r--src/include/usr/pnor/pnorif.H1
-rw-r--r--src/usr/pnor/pnorrp.C14
-rw-r--r--src/usr/pnor/spnorrp.C217
-rw-r--r--src/usr/pnor/spnorrp.H13
-rw-r--r--src/usr/runtime/populate_hbruntime.C26
-rw-r--r--src/usr/secureboot/base/securerommgr.C2
-rw-r--r--src/usr/secureboot/common/containerheader.C3
-rw-r--r--src/usr/util/runtime/utillidmgr_rt.C23
-rw-r--r--src/usr/util/utillidpnor.C8
-rw-r--r--src/usr/vfs/vfsrp.C2
-rw-r--r--src/usr/vfs/vfsrp.H2
15 files changed, 287 insertions, 62 deletions
diff --git a/src/build/buildpnor/genPnorImages.pl b/src/build/buildpnor/genPnorImages.pl
index 74b317c3a..eae4e1fe7 100755
--- a/src/build/buildpnor/genPnorImages.pl
+++ b/src/build/buildpnor/genPnorImages.pl
@@ -74,6 +74,7 @@ use constant VFS_MODULE_TABLE_MAX_SIZE => VFS_EXTENDED_MODULE_MAX
# Flag parameter string passed into signing tools
# Note spaces before/after are critical.
use constant OP_SIGNING_FLAG => " --flags ";
+use constant SW_FLAG_HAS_A_HPT => 0x80000000;
# Security bits HW flag strings
use constant OP_BUILD_FLAG => 0x80000000;
use constant FIPS_BUILD_FLAG => 0x40000000;
@@ -464,7 +465,10 @@ sub manipulateImages
# Partitions that have a hash page table at the beginning of the section
# for secureboot purposes.
- my %hashPageTablePartitions = (HBI => 1);
+ # TODO: add back SBE and HCODE as per story 209485
+ my %hashPageTablePartitions = (HBI => 1,
+ WOFDATA => 1,
+ MEMD => 1);
if($ENV{'RM_HASH_PAGE_TABLE'})
{
undef %hashPageTablePartitions;
@@ -514,24 +518,24 @@ sub manipulateImages
# Sections that have secureboot support. Secureboot still must be
# enabled for secureboot actions on these partitions to occur.
my $isNormalSecure = ($eyeCatch eq "HBBL");
- $isNormalSecure ||= ($eyeCatch eq "SBE");
- $isNormalSecure ||= ($eyeCatch eq "MEMD");
$isNormalSecure ||= ($eyeCatch eq "HBRT");
$isNormalSecure ||= ($eyeCatch eq "PAYLOAD");
$isNormalSecure ||= ($eyeCatch eq "OCC");
$isNormalSecure ||= ($eyeCatch eq "CAPP");
$isNormalSecure ||= ($eyeCatch eq "BOOTKERNEL");
- $isNormalSecure ||= ($eyeCatch eq "HCODE");
- $isNormalSecure ||= ($eyeCatch eq "CENHWIMG");
- $isNormalSecure ||= ($eyeCatch eq "WOFDATA");
$isNormalSecure ||= ($eyeCatch eq "IMA_CATALOG");
$isNormalSecure ||= ($eyeCatch eq "TESTRO");
$isNormalSecure ||= ($eyeCatch eq "TESTLOAD");
$isNormalSecure ||= ($eyeCatch eq "VERSION");
+ $isNormalSecure ||= ($eyeCatch eq "CENHWIMG");
+ $isNormalSecure ||= ($eyeCatch eq "SBE");
+ $isNormalSecure ||= ($eyeCatch eq "HCODE");
my $isSpecialSecure = ($eyeCatch eq "HBB");
$isSpecialSecure ||= ($eyeCatch eq "HBD");
$isSpecialSecure ||= ($eyeCatch eq "HBI");
+ $isSpecialSecure ||= ($eyeCatch eq "WOFDATA");
+ $isSpecialSecure ||= ($eyeCatch eq "MEMD");
# Used to indicate security is supported in firmware
my $secureSupported = $isNormalSecure || $isSpecialSecure;
@@ -670,6 +674,9 @@ sub manipulateImages
else
{
run_command("cp $tempImages{hashPageTable} $tempImages{PAYLOAD_TEXT}");
+ # Hash table generated so need to set sw-flags
+ my $hex_sw_flag = sprintf("0x%08X", SW_FLAG_HAS_A_HPT);
+ $CUR_OPEN_SIGN_REQUEST .= " --sw-flags $hex_sw_flag ";
}
run_command("$CUR_OPEN_SIGN_REQUEST "
diff --git a/src/include/securerom/ROM.H b/src/include/securerom/ROM.H
index f4cf76528..0d97537e0 100644
--- a/src/include/securerom/ROM.H
+++ b/src/include/securerom/ROM.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -284,7 +284,7 @@ enum HW_SB_FLAGS
// SW Security Flags
enum SW_SB_FLAGS
{
- // placeholder
+ HASH_PAGE_TABLE_FLAG = 0x80000000
};
// Structure to store all hw and sw flag values in a container header
@@ -295,7 +295,8 @@ struct sb_flags_t
hw_opal(false),
hw_phyp(false),
hw_lab_override(false),
- hw_key_transition(false)
+ hw_key_transition(false),
+ sw_hash(false)
{
}
@@ -305,6 +306,7 @@ struct sb_flags_t
bool hw_lab_override; ///< Whether to enable lab security override;
///< Only applicable for SBE partition
bool hw_key_transition; ///< Indicates this is a key transition container
+ bool sw_hash; ///< Indicates presence of hash page table
};
/**
diff --git a/src/include/usr/pnor/pnor_const.H b/src/include/usr/pnor/pnor_const.H
index 41d1ebdee..44050eb50 100644
--- a/src/include/usr/pnor/pnor_const.H
+++ b/src/include/usr/pnor/pnor_const.H
@@ -111,7 +111,8 @@ struct SectionInfo_t
reprovision(false),
Volatile(false),
secure(false),
- clearOnEccErr(false)
+ clearOnEccErr(false),
+ hasHashTable(false)
{}
SectionId id; /**< Identifier for this section */
const char* name; /**< Name of the section */
@@ -126,6 +127,7 @@ struct SectionInfo_t
bool Volatile; /**< Section loses contents on non HB reboots */
bool secure; /**< Indicates if a section is secure */
bool clearOnEccErr; /**< Indicates on ECC errors, clear and reboot*/
+ bool hasHashTable; /**< Indicates if there exists a hash page table*/
size_t secureProtectedPayloadSize; /**< Cache the secure payload size so
that the secure container only
needs to be parsed once */
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index fb7435a33..10c3e7b22 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -98,8 +98,7 @@ namespace PNOR
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_VERIFY_PAGE = 0xD0, /**< SPnorRP::verify_page */
MOD_SPNORRP_DIDSTARTUPFAIL = 0xD1, /**< didSecureStartupFail(rc) */
MOD_SPNORRP_ALLOCATE_BLOCK = 0xD2, /**< SPnorRP::initDaemon */
MOD_SPNORRP_WAITFORMESSAGE = 0xD3, /**< SPnorRP::waitForMessage */
@@ -192,7 +191,7 @@ namespace PNOR
RC_NOT_PAGE_ALIGNED = PNOR_COMP_ID | 0x3B,
RC_SECURE_PRO_SIZE_MISMATCH = PNOR_COMP_ID | 0x3C,
RC_READ_ONLY_PERM_FAIL = PNOR_COMP_ID | 0x3D,
-
+ RC_VERIFY_PAGE_FAILED = PNOR_COMP_ID | 0x3E,
//@fixme-RTC:131607-Temporary value to allow HWSV compile
//termination_rc
RC_PNOR_CORRUPTION = PNOR_COMP_ID | 0x99,
diff --git a/src/include/usr/pnor/pnorif.H b/src/include/usr/pnor/pnorif.H
index 11cc98a10..835c100d7 100644
--- a/src/include/usr/pnor/pnorif.H
+++ b/src/include/usr/pnor/pnorif.H
@@ -269,7 +269,6 @@ bool cmpSecurebootMagicNumber(const uint8_t* i_vaddr);
* False otherwise.
*/
bool isSectionEmpty(const PNOR::SectionId i_section);
-
} // PNOR
#endif
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index af6ccf3fa..cb70eb94c 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -522,6 +522,7 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
#ifdef CONFIG_SECUREBOOT
o_info.secure = iv_TOC[id].secure;
+ o_info.size = iv_TOC[id].size;
o_info.secureProtectedPayloadSize = 0; // for non secure sections
// the protected payload size
// defaults to zero
@@ -591,6 +592,17 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
// was done previously in pnor_common.C
o_info.size -= PAGESIZE;
+ // Need to change size to accommodate for hash table
+ if (l_conHdr.sb_flags()->sw_hash)
+ {
+ o_info.vaddr += payloadTextSize;
+ // Hash page table needs to use containerSize as the base
+ // and subtract off header and hash table size
+ o_info.size = l_conHdr.totalContainerSize() - PAGE_SIZE -
+ payloadTextSize;
+ o_info.hasHashTable = true;
+ }
+
// cache the value in SectionInfo struct so that we can
// parse the container header less often
o_info.secureProtectedPayloadSize = payloadTextSize;
@@ -598,11 +610,11 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
else
#endif
{
+ o_info.size = iv_TOC[id].size;
o_info.vaddr = iv_TOC[id].virtAddr;
}
o_info.flashAddr = iv_TOC[id].flashAddr;
- o_info.size = iv_TOC[id].size;
o_info.eccProtected = ((iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT)
!= 0) ? true : false;
o_info.sha512Version = ((iv_TOC[id].version & FFS_VERS_SHA512)
diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C
index 5b1ef5b03..a58f1c566 100644
--- a/src/usr/pnor/spnorrp.C
+++ b/src/usr/pnor/spnorrp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -41,6 +41,7 @@
#include <secureboot/trustedbootif.H>
#include <secureboot/header.H>
#include <sys/task.h>
+#include <arch/ppc.H>
extern trace_desc_t* g_trac_pnor;
@@ -363,6 +364,15 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
PNOR::SectionIdToString(i_id));
}
+ // If hash table exists, need to adjust sizes
+ if (l_info.hasHashTable)
+ {
+ io_rec->hasHashTable = true;
+ l_info.vaddr -= l_info.secureProtectedPayloadSize;
+ l_info.size += l_info.secureProtectedPayloadSize;
+ io_rec->hashTableVaddr = l_info.vaddr;
+ }
+
l_info.vaddr -= PAGESIZE; // back up a page to expose the secure header
l_info.size += PAGESIZE; // add a page to size to account for the header
@@ -643,13 +653,23 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
SHA512_DIGEST_LENGTH);
}
- // set permissions on the secured pages to writable
+ // set permissions to be writable
+ // in the case of HPT this is the header + HPT
+ // in the case of no HPT this is the header + text region
l_errhdl = setPermission(io_rec->secAddr, l_protectedSizeWithHdr,
WRITABLE);
- if(l_errhdl)
+ if (l_errhdl)
{
- TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
- "failed on text section");
+ if (l_info.hasHashTable)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::verifySections set permissions "
+ "failed on header + hash page table");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::verifySections set permissions "
+ "failed on header + text section");
+ }
break;
}
@@ -691,10 +711,18 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
break;
}
-
- l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
- unprotectedPayloadSize,
- WRITABLE | WRITE_TRACKED);
+ if (l_info.hasHashTable)
+ {
+ l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize,
+ READ_ONLY);
+ }
+ else
+ {
+ l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize,
+ WRITABLE | WRITE_TRACKED);
+ }
if(l_errhdl)
{
TRACFCOMP(g_trac_pnor,"SPnorRP::verifySections set permissions "
@@ -704,8 +732,11 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
// Register the write tracked memory range to be flushed on
// shutdown.
- INITSERVICE::registerBlock(io_rec->secAddr + l_protectedSizeWithHdr,
- unprotectedPayloadSize, SPNOR_PRIORITY);
+ if (!l_info.hasHashTable)
+ {
+ INITSERVICE::registerBlock(io_rec->secAddr + l_protectedSizeWithHdr,
+ unprotectedPayloadSize, SPNOR_PRIORITY);
+ }
}
else
{
@@ -738,6 +769,83 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
return l_rc;
}
+int64_t getHashPageTableIndex(const int64_t i_vaddr)
+{
+ return (i_vaddr / static_cast<int64_t>(PAGE_SIZE)) + 1;
+}
+
+
+PAGE_TABLE_ENTRY_t* getHashPageTableEntry(const int64_t i_vaddr,
+ const uint64_t i_hash_vaddr)
+{
+ int64_t l_index = getHashPageTableIndex(i_vaddr);
+ int64_t l_offset = l_index * HASH_PAGE_TABLE_ENTRY_SIZE;
+
+ // l_offset is the offset for the start of the hash page table
+ // i_hash_vaddr is the vaddr for the start of the hash in SECURE
+ // subtract off DELTA of 3GB to get into TEMP space
+ return reinterpret_cast<PAGE_TABLE_ENTRY_t*>(l_offset + i_hash_vaddr -
+ VMM_VADDR_SPNOR_DELTA);
+}
+
+errlHndl_t verify_page(const int64_t i_offset_vaddr, const uint64_t i_hash_vaddr,
+ const uint64_t i_hash_size)
+{
+ errlHndl_t l_errl = nullptr;
+
+ // Get current hash page table entry in TEMP space
+ PAGE_TABLE_ENTRY_t* l_pageTableEntry =
+ getHashPageTableEntry(i_offset_vaddr, i_hash_vaddr);
+
+ // Get previous hash page table entry in TEMP space
+ PAGE_TABLE_ENTRY_t* l_prevPageTableEntry =
+ getHashPageTableEntry(i_offset_vaddr - PAGE_SIZE, i_hash_vaddr);
+
+ // Concatenate previous hash with current page data
+ std::vector< std::pair<void*,size_t> > l_blobs;
+ l_blobs.push_back(std::make_pair<void*,size_t>(l_prevPageTableEntry,
+ HASH_PAGE_TABLE_ENTRY_SIZE));
+
+ // To get to PNOR space, we have the address of the hash in SECURE space and
+ // we add hash table size to get passed the hash page table. Then we add
+ // i_offset_vaddr, the offset of the requested vaddr, to end up at the
+ // requested vaddr in SECURE space. Finally we subtract off 2 DELTAS of
+ // 3GB each to get to the requested vaddr in PNOR space
+ l_blobs.push_back(std::make_pair<void*,size_t>(
+ reinterpret_cast<void*>(i_offset_vaddr +
+ i_hash_vaddr + i_hash_size -
+ 2 * VMM_VADDR_SPNOR_DELTA),
+ PAGE_SIZE));
+ SHA512_t l_curPageHash = {0};
+ SECUREBOOT::hashConcatBlobs(l_blobs, l_curPageHash);
+
+ // Compare existing hash page table entry with the derived one.
+ if (memcmp(l_pageTableEntry,l_curPageHash,HASH_PAGE_TABLE_ENTRY_SIZE) != 0)
+ {
+ TRACFCOMP(g_trac_pnor, "ERROR:>PNOR::verify_page secureboot verify fail on vaddr 0x%016llX",
+ i_hash_vaddr + i_hash_size + i_offset_vaddr);
+ /*@
+ * @severity ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid MOD_SPNORRP_VERIFY_PAGE
+ * @reasoncode RC_VERIFY_PAGE_FAILED
+ * @userdata1 Kernel RC
+ * @userdata2 Virtual address accessed
+ *
+ * @devdesc Secureboot page verify failure
+ * @custdesc Corrupted flash image or firmware error during system boot
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ MOD_SPNORRP_VERIFY_PAGE,
+ RC_VERIFY_PAGE_FAILED,
+ TO_UINT64(EACCES),
+ i_offset_vaddr,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ }
+ return l_errl;
+}
+
/**
@@ -769,6 +877,7 @@ void SPnorRP::waitForMessage()
// data[0] = virtual address requested
// data[1] = address to place contents
+ uint64_t requested_vaddr = message->data[0];
eff_addr = reinterpret_cast<uint8_t*>(message->data[0]);
user_addr = reinterpret_cast<uint8_t*>(message->data[1]);
@@ -819,10 +928,34 @@ void SPnorRP::waitForMessage()
TRACDCOMP( g_trac_pnor, "SPnorRP::waitForMessage got a"
" request to read from secure space - "
"message : user_addr=%p, eff_addr=%p, msgtype=%d, "
- "textSize=0x%.16llX secAddr0x%.16llX", user_addr,
+ "textSize=0x%.16llX secAddr=0x%.16llX", user_addr,
eff_addr, message->type, l_rec.textSize,
l_rec.secAddr);
+ // If record has an associated hash page table, then we
+ // want to verify the page with the hash table in temp
+ if (SECUREBOOT::enabled() && l_rec.hasHashTable)
+ {
+ // Pass in the offset of just the data
+ int64_t offset_vaddr = requested_vaddr -
+ l_rec.hashTableVaddr - l_rec.textSize;
+
+ // There is no hash table entry when we try to
+ // verify the header
+ if (offset_vaddr >= 0) {
+ l_errhdl = verify_page(offset_vaddr,
+ l_rec.hashTableVaddr,
+ l_rec.textSize);
+ }
+
+ if (l_errhdl)
+ {
+ SECUREBOOT::handleSecurebootFailure(l_errhdl, false, true);
+ status_rc = -EFAULT;
+ break;
+ }
+ }
+
// determine the source of the data depending on
// whether it is part of the secure payload.
// by the way, this if could be removed to make this
@@ -843,8 +976,8 @@ void SPnorRP::waitForMessage()
// if the page came from temp space then free up
// the temp page now that we're done with it
// NOTE: secAddr points to Secure Header
- if (eff_addr < ( (l_rec.secAddr + PAGESIZE) +
- l_rec.textSize))
+ if (!l_rec.hasHashTable && (eff_addr < ( (l_rec.secAddr + PAGESIZE) +
+ l_rec.textSize)))
{
mm_remove_pages(RELEASE, eff_addr - delta,
PAGESIZE);
@@ -924,7 +1057,6 @@ void SPnorRP::waitForMessage()
// cache the record to use fields later as hints
l_rec = *l_record;
-
} while (0);
}
break;
@@ -936,7 +1068,7 @@ void SPnorRP::waitForMessage()
do {
// Disallow unload of HBB, HBI and Targeting
if (l_id == HB_BASE_CODE ||
- l_id == HB_EXT_CODE ||
+ l_id == HB_EXT_CODE ||
l_id == HB_DATA)
{
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::waitForMessage> Secure unload of HBB, HBI, and targeting is not allowed secId=%d", l_id);
@@ -998,7 +1130,7 @@ void SPnorRP::waitForMessage()
size_t l_sizeWithHdr = PAGESIZE + l_rec->textSize;
// if the section has an unsecured portion
- if (l_sizeWithHdr != l_rec->infoSize)
+ if (l_sizeWithHdr != l_rec->infoSize && !l_rec->hasHashTable)
{
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::waitForMessage> Attempting to unload an unsupported section: 0x%X textsize+hdr: 0x%llX infosize: 0x%llX (the two sizes must be equal)", l_id, l_sizeWithHdr, l_rec->infoSize);
/*@
@@ -1031,6 +1163,40 @@ void SPnorRP::waitForMessage()
}
TRACDCOMP(g_trac_pnor,"Completely unloading %s", PNOR::SectionIdToString(l_id));
+ if (l_rec->hasHashTable)
+ {
+ // remove unprotected pages
+ l_errhdl = removePages(l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,
+ ERR_MRK"SPnorRP::waitForMessage> "
+ "removePages failed for address "
+ "0x%11X of length 0x%11X",
+ l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+ status_rc = -EFAULT;
+ break;
+ }
+
+ l_errhdl = setPermission(l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize,
+ NO_ACCESS);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor,
+ ERR_MRK"SPnorRP::waitForMessage> "
+ "setPermission failed for address "
+ "0x%11X of length 0x%11X",
+ l_rec->secAddr + PAGE_SIZE + l_rec->textSize,
+ l_rec->infoSize - PAGE_SIZE - l_rec->textSize);
+
+ status_rc = -EFAULT;
+ break;
+ }
+ }
+
l_errhdl = removePages(l_rec->secAddr,
l_sizeWithHdr);
if (l_errhdl)
@@ -1039,21 +1205,21 @@ void SPnorRP::waitForMessage()
ERR_MRK"SPnorRP::waitForMessage> "
"removePages failed for address "
"0x%llX of length 0x%llX", l_rec->secAddr,
- l_sizeWithHdr);
+ l_sizeWithHdr);
status_rc = -EFAULT;
break;
}
l_errhdl = setPermission(l_rec->secAddr,
- l_sizeWithHdr,
- NO_ACCESS);
+ l_sizeWithHdr,
+ NO_ACCESS);
if (l_errhdl)
{
TRACFCOMP( g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"setPermission failed for address "
"0x%llX of length 0x%llX", l_rec->secAddr,
- l_sizeWithHdr);
+ l_sizeWithHdr);
status_rc = -EFAULT;
break;
@@ -1067,7 +1233,7 @@ void SPnorRP::waitForMessage()
l_sizeWithHdr);
if (l_errhdl)
{
- TRACFCOMP( g_trac_pnor,
+ TRACFCOMP(g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"removePages failed for address "
"0x%llX of length 0x%llX", l_tempAddr,
@@ -1083,16 +1249,15 @@ void SPnorRP::waitForMessage()
l_sizeWithHdr);
l_errhdl = setPermission(l_tempAddr,
- l_sizeWithHdr,
- NO_ACCESS);
+ l_sizeWithHdr,
+ NO_ACCESS);
if (l_errhdl)
{
- TRACFCOMP( g_trac_pnor,
+ TRACFCOMP(g_trac_pnor,
ERR_MRK"SPnorRP::waitForMessage> "
"setPermission failed for address "
"0x%llX of length 0x%llX", l_tempAddr,
l_sizeWithHdr);
-
status_rc = -EFAULT;
break;
}
diff --git a/src/usr/pnor/spnorrp.H b/src/usr/pnor/spnorrp.H
index 11da539ef..578858e5e 100644
--- a/src/usr/pnor/spnorrp.H
+++ b/src/usr/pnor/spnorrp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -113,13 +113,16 @@ class SPnorRP
* Keep track of secured payload size and secure section addresses
*/
struct LoadRecord{
- uint8_t* secAddr;
- size_t textSize;
- size_t infoSize;
+ uint8_t* secAddr; // virtual address of the start of the record
+ uint64_t hashTableVaddr; // virtual address of the hash table (if it exists)
+ size_t textSize; // size of the protected payload, not including header
+ size_t infoSize; // size of the entire partition
size_t refCount;
+ bool hasHashTable; // indicates if the record has a hash table
+
SHA512_t payloadTextHash;
LoadRecord()
- :secAddr(nullptr), textSize(0), infoSize(0), refCount(0)
+ :secAddr(nullptr), hashTableVaddr(0), textSize(0), infoSize(0), refCount(0), hasHashTable(false)
{
memset(&payloadTextHash[0], 0, SHA512_DIGEST_LENGTH);
}
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 371c3bee8..813620ddd 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -854,9 +854,18 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
}
#ifdef CONFIG_SECUREBOOT
- memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
- reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
- l_memd_info.secureProtectedPayloadSize);
+ if (l_memd_info.hasHashTable)
+ {
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.size);
+ }
+ else
+ {
+ memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
+ reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
+ l_memd_info.secureProtectedPayloadSize);
+ }
#else
memcpy(reinterpret_cast<uint8_t*>(l_prevDataAddr),
reinterpret_cast<uint8_t *>(l_memd_info.vaddr),
@@ -1009,7 +1018,16 @@ errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec,
if (i_secHdrExpected)
{
// If section is signed, only the protected size was loaded into memory
- l_imgSize = l_info.secureProtectedPayloadSize;
+ if (!l_info.hasHashTable)
+ {
+ l_imgSize = l_info.secureProtectedPayloadSize;
+ }
+ else
+ {
+ // Need to expose header and hash table
+ l_pnorVaddr -= l_info.secureProtectedPayloadSize;
+ l_imgSize += l_info.secureProtectedPayloadSize;
+ }
// Include secure header
// NOTE: we do not preserve the header in virtual memory when SB
// is compiled out. So "-PAGESIZE" only works when SB is compiled in
diff --git a/src/usr/secureboot/base/securerommgr.C b/src/usr/secureboot/base/securerommgr.C
index 17becb6b6..87a9dccc9 100644
--- a/src/usr/secureboot/base/securerommgr.C
+++ b/src/usr/secureboot/base/securerommgr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/usr/secureboot/common/containerheader.C b/src/usr/secureboot/common/containerheader.C
index 53baa5afc..28c2c551f 100644
--- a/src/usr/secureboot/common/containerheader.C
+++ b/src/usr/secureboot/common/containerheader.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -514,6 +514,7 @@ void ContainerHeader::parseFlags()
& LAB_OVERRIDE_FLAG);
iv_sbFlags.hw_key_transition =( iv_headerInfo.hw_prefix_hdr.flags
& KEY_TRANSITION_FLAG);
+ iv_sbFlags.sw_hash = iv_headerInfo.sw_hdr.flags & HASH_PAGE_TABLE_FLAG;
}
#ifndef __HOSTBOOT_RUNTIME
diff --git a/src/usr/util/runtime/utillidmgr_rt.C b/src/usr/util/runtime/utillidmgr_rt.C
index ad5a7cd48..55bebdeb3 100644
--- a/src/usr/util/runtime/utillidmgr_rt.C
+++ b/src/usr/util/runtime/utillidmgr_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -192,13 +192,24 @@ errlHndl_t UtilLidMgr::loadLid()
UTIL_FT(ERR_MRK"UtilLidMgr::loadLid - setheader failed");
break;
}
- iv_lidSize = l_conHdr.payloadTextSize();
UTIL_FT("UtilLidMgr::loadLid - resv mem section has secure header");
-
- // Increment by page size to not expose secure header
- iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
- PAGESIZE;
+ if (l_conHdr.sb_flags()->sw_hash)
+ {
+ // Size of lid has to be size of unprotected data. So we
+ // need to take out header and hash table sizes
+ iv_lidSize = l_conHdr.totalContainerSize() - PAGESIZE -
+ l_conHdr.payloadTextSize();
+ iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
+ PAGESIZE + l_conHdr.payloadTextSize();
+ }
+ else
+ {
+ iv_lidSize = l_conHdr.payloadTextSize();
+ // Increment by page size to not expose secure header
+ iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
+ PAGESIZE;
+ }
}
}
else if(iv_isLidInVFS)
diff --git a/src/usr/util/utillidpnor.C b/src/usr/util/utillidpnor.C
index 7e910f6eb..8d81ad0c1 100644
--- a/src/usr/util/utillidpnor.C
+++ b/src/usr/util/utillidpnor.C
@@ -179,7 +179,13 @@ errlHndl_t UtilLidMgr::getLidPnorSectionInfo(const uint32_t i_lidId,
// downstream logic from going past the end of the image.
// NOTE: This assumes that any secure lid loaded from PNOR by
// UtilLidMgr does not contain an unprotected section
- iv_lidPnorInfo.size = iv_lidPnorInfo.secureProtectedPayloadSize;
+ // In this case of hash tables, we need to load the entire
+ // partition size because the user data is part of the
+ // unprotected payload
+ if (!iv_lidPnorInfo.hasHashTable)
+ {
+ iv_lidPnorInfo.size = iv_lidPnorInfo.secureProtectedPayloadSize;
+ }
}
#endif
#endif
diff --git a/src/usr/vfs/vfsrp.C b/src/usr/vfs/vfsrp.C
index fde05d820..a200bcaab 100644
--- a/src/usr/vfs/vfsrp.C
+++ b/src/usr/vfs/vfsrp.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
diff --git a/src/usr/vfs/vfsrp.H b/src/usr/vfs/vfsrp.H
index ebf9c86fd..7530445c1 100644
--- a/src/usr/vfs/vfsrp.H
+++ b/src/usr/vfs/vfsrp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
OpenPOWER on IntegriCloud