summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2017-11-21 16:09:22 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-12-05 14:37:19 -0500
commitca52131dad3de16f44b9c9f07b5413edf1e9742a (patch)
tree56a0fcd4357510dee0fa25883dea463cfdb1433b /src
parent89f7297255af3b70c6c1f7a3845498d13eff5cfd (diff)
downloadtalos-hostboot-ca52131dad3de16f44b9c9f07b5413edf1e9742a.tar.gz
talos-hostboot-ca52131dad3de16f44b9c9f07b5413edf1e9742a.zip
Handle ContainerHeader asserts more nicely with error logs
Change-Id: I2dfd02bd7c7f5b5356cd93ca967482c2d7f79ec1 RTC: 178520 RTC: 181899 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49966 Tested-by: Jenkins Server <pfd-jenkins+hostboot@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> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/secureboot/containerheader.H78
-rw-r--r--src/include/usr/secureboot/secure_reasoncodes.H5
-rw-r--r--src/usr/pnor/pnorrp.C35
-rw-r--r--src/usr/pnor/spnorrp.C39
-rw-r--r--src/usr/runtime/preverifiedlidmgr.C9
-rw-r--r--src/usr/sbe/sbe_update.C8
-rw-r--r--src/usr/secureboot/base/test/securerommgrtest.H46
-rw-r--r--src/usr/secureboot/common/containerheader.C195
-rw-r--r--src/usr/secureboot/trusted/base/trustedboot_base.C8
-rw-r--r--src/usr/util/runtime/utillidmgr_rt.C38
-rw-r--r--src/usr/util/utilmclmgr.C8
11 files changed, 330 insertions, 139 deletions
diff --git a/src/include/usr/secureboot/containerheader.H b/src/include/usr/secureboot/containerheader.H
index b5edfb325..1905ac39d 100644
--- a/src/include/usr/secureboot/containerheader.H
+++ b/src/include/usr/secureboot/containerheader.H
@@ -30,6 +30,9 @@
#include <securerom/ROM.H>
#include <limits.h>
#include <array>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <initservice/initserviceif.H>
// Forward Declaration
class SecureRomManagerTest;
@@ -45,38 +48,36 @@ class ContainerHeader
public:
/**
- * @brief ContainerHeader
- *
- * This constructor parses the input container header and sets values
- * accordingly so they can be retrieved later.
- *
- * @param[in] i_header Secure container header to parse.
- * NULL input will assert
+ * @brief Default Constructor
*/
- ContainerHeader(const void* i_header):
- iv_isValid(false),iv_hdrBytesRead(0)
- {
- assert(i_header != nullptr);
- iv_pHdrStart = reinterpret_cast<const uint8_t*>(i_header);
- initVars();
- parse_header(i_header);
- };
+ ContainerHeader():
+ iv_componentId{}, iv_headerInfo{}, iv_isValid(false),
+ iv_pHdrStart(nullptr), iv_hdrBytesRead(0), iv_totalSwKeysSize(0),
+ iv_sbFlags{}, iv_hwKeyHash{}, iv_fakeHeader{}
+ {}
/**
- * @brief ContainerHeader - generate fake header
+ * @brief Sets Container header from virtual address provided and parses
+ * to set values accordingly so they can be retrieved later.
*
- * This constructor generates a fake header with minimal information
+ * @param[in] i_header virtual address pointing to a secure container
+ * header to parse.
+ * nullptr input will assert
+ * @return Error handle if error; otherwise nullptr
+ */
+ errlHndl_t setHeader(const void* i_header);
+
+ /**
+ * @brief Same as setHeader(), but generates a fake header from
+ * minimal input and then parses the header
*
* @param[in] i_totalSize Total Container Size
* @param[in] i_compId Component ID
+ *
+ * @return Error handle if error; otherwise nullptr
*/
- ContainerHeader(const size_t i_totalSize,
- const char* i_compId):
- iv_isValid(false),iv_hdrBytesRead(0),iv_fakeHeader{}
- {
- initVars();
- genFakeHeader(i_totalSize, i_compId);
- };
+ errlHndl_t setFakeHeader(const size_t i_totalSize,
+ const char* i_compId);
/**
* @brief Initialize internal variables
@@ -187,11 +188,6 @@ class ContainerHeader
const uint8_t* fakeHeader() const;
private:
- /**
- * @brief Default Constructor in private to prevent being instantiated
- * by non friend/children derivatives.
- */
- ContainerHeader(){};
/**
* @brief Complete container header structure based on ROM structures
@@ -253,8 +249,9 @@ class ContainerHeader
/**
* @brief Weak check to determine if secureboot header looks right.
* Also sets iv_isValid private member
+ * @return Error handle if error; otherwise nullptr
*/
- void validate();
+ errlHndl_t validate();
/**
* @brief Print out useful sections of the container header
@@ -266,32 +263,35 @@ class ContainerHeader
*
* Parses a secure container header defined by ROM structures and set
* internal header structure.
+ * Note: nullptr header will assert
*
- * @param[in] i_containerHdr Secure container header to parse
- * NULL input will assert
+ * @return Error handle if error; otherwise nullptr
*/
- void parse_header(const void* i_header);
+ errlHndl_t parse_header();
/**
* @brief Checks bounds of parsing before mempy and increments pointer
*
* Ensures that we don't memcpy more bytes than the max size of a
- * secure container header. Asserts on out of bounds memcpy.
+ * secure container header. Error log created on out of bounds memcpy.
*
* @param[in] i_dest Pointer to the memory location to copy to
- * NULL input will assert
+ * nullptr input will assert
* @param[in] io_hdr Pointer to current location of container header
- * NULL input will assert
+ * nullptr input will assert
* @param[in] i_size Number of bytes to copy
+ *
+ * @return Error handle if error; otherwise nullptr
*/
- void safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
- const size_t i_size);
+ errlHndl_t safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
+ const size_t i_size);
// Pointer to fake header generated
std::array<uint8_t,PAGE_SIZE> iv_fakeHeader;
/**
- * @brief Generate fake header with limited information
+ * @brief Generate fake header with minimal information and stores in
+ * instance variable
*
* @param[in] i_totalSize Total container size
* @param[in] i_compId Component ID
diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H
index f633ef7b2..21c195b77 100644
--- a/src/include/usr/secureboot/secure_reasoncodes.H
+++ b/src/include/usr/secureboot/secure_reasoncodes.H
@@ -41,6 +41,9 @@ namespace SECUREBOOT
MOD_SECURE_WRITE_REG = 0x07,
MOD_SECURE_SETTINGS_INIT = 0x08,
MOD_SECURE_VERIFY_COMPONENT = 0x09,
+ MOD_SECURE_CONT_HDR_PARSE = 0x0A,
+ MOD_SECURE_CONT_HDR_CPY_INC = 0x0B,
+ MOD_SECURE_CONT_VALIDATE = 0x0C,
};
enum SECUREReasonCode
@@ -56,6 +59,8 @@ namespace SECUREBOOT
RC_SECURE_BAD_TARGET = SECURE_COMP_ID | 0x09,
RC_SECURE_BOOT_DISABLED = SECURE_COMP_ID | 0x0A,
RC_SECROM_INVALID = SECURE_COMP_ID | 0x0B,
+ RC_CONT_HDR_NO_SPACE = SECURE_COMP_ID | 0x0C,
+ RC_CONT_HDR_INVALID = SECURE_COMP_ID | 0x0D,
// Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H
};
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index c3deb16ed..da2548ebc 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -599,37 +599,16 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section,
// Do an existence check on the container to see if it's non-empty
// and has valid beginning bytes. For optional Secure PNOR sections.
- if (PNOR::cmpSecurebootMagicNumber(l_vaddr))
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errhdl = l_conHdr.setHeader(l_vaddr);
+ if (l_errhdl)
{
- SECUREBOOT::ContainerHeader l_conHdr(l_vaddr);
- payloadTextSize = l_conHdr.payloadTextSize();
- assert(payloadTextSize > 0,"Non-zero payload text size expected.");
- }
- else
- {
- uint32_t l_badMagicHeader = 0;
- memcpy(&l_badMagicHeader, l_vaddr, sizeof(ROM_MAGIC_NUMBER));
- TRACFCOMP( g_trac_pnor, ERR_MRK"PnorRP::getSectionInfo: magic number not valid to parse container for section = %s magic number = 0x%X",
- o_info.name, l_badMagicHeader);
- /*@
- * @errortype
- * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
- * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO
- * @reasoncode PNOR::RC_BAD_SECURE_MAGIC_NUM
- * @userdata1 Requested Section
- * @userdata2 Bad magic number
- * @devdesc PNOR section does not have the known secureboot magic number
- * @custdesc Corrupted flash image or firmware error during system boot
- */
- l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- PNOR::MOD_PNORRP_GETSECTIONINFO,
- PNOR::RC_BAD_SECURE_MAGIC_NUM,
- TO_UINT64(i_section),
- TO_UINT64(l_badMagicHeader),
- true /*Add HB SW Callout*/);
- l_errhdl->collectTrace(PNOR_COMP_NAME);
+ TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::getSectionInfo: setheader failed");
break;
}
+ payloadTextSize = l_conHdr.payloadTextSize();
+ assert(payloadTextSize > 0,"Non-zero payload text size expected.");
+
// skip secure header for secure sections at this point in time
o_info.vaddr += PAGESIZE;
// now that we've skipped the header we also need to adjust the
diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C
index b45ac3e71..b9fd587c6 100644
--- a/src/usr/pnor/spnorrp.C
+++ b/src/usr/pnor/spnorrp.C
@@ -423,7 +423,14 @@ uint64_t SPnorRP::verifySections(SectionId i_id,
memcpy(l_tempAddr, l_unsecuredAddr, l_info.secureProtectedPayloadSize
+ PAGESIZE); // plus header size
- SECUREBOOT::ContainerHeader l_conHdr(l_tempAddr);
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errhdl = l_conHdr.setHeader(l_tempAddr);
+ if (l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::verifySections> setheader failed");
+ break;
+ }
+
size_t l_totalContainerSize = l_conHdr.totalContainerSize();
auto l_prefixHdrFlags = l_conHdr.prefixHeaderFlags();
@@ -1195,6 +1202,7 @@ errlHndl_t SPnorRP::baseExtVersCheck(const uint8_t *i_vaddr) const
errlHndl_t l_errl = NULL;
assert(i_vaddr != NULL);
+ do {
// Check if measured and build time hashes of HBB sw signatures match.
// Query the HBB header
const void* l_pHbbHeader = NULL;
@@ -1202,7 +1210,13 @@ errlHndl_t SPnorRP::baseExtVersCheck(const uint8_t *i_vaddr) const
// Fatal code bug if either address is NULL
assert(l_pHbbHeader!=NULL,"ERORR: Cached header address is NULL");
// Build a container header object from the raw header
- SECUREBOOT::ContainerHeader l_hbbContainerHeader(l_pHbbHeader);
+ SECUREBOOT::ContainerHeader l_hbbContainerHeader;
+ l_errl = l_hbbContainerHeader.setHeader(l_pHbbHeader);
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::baseExtVersCheck> setheader failed");
+ break;
+ }
// Calculate hash of HBB's sw signatures
SHA512_t l_hashSwSigs = {0};
@@ -1251,8 +1265,11 @@ errlHndl_t SPnorRP::baseExtVersCheck(const uint8_t *i_vaddr) const
TO_UINT64(*reinterpret_cast<const uint64_t*>(l_hashPageTableSaltEntry)));
l_errl->collectTrace(PNOR_COMP_NAME);
l_errl->collectTrace(SECURE_COMP_NAME);
+ break;
}
+ } while(0);
+
return l_errl;
}
@@ -1263,7 +1280,13 @@ errlHndl_t SPnorRP::keyTransitionCheck(const uint8_t *i_vaddr) const
do {
// Check if the header flags have the key transition bit set
- SECUREBOOT::ContainerHeader l_outerConHdr(i_vaddr);
+ SECUREBOOT::ContainerHeader l_outerConHdr;
+ l_errl = l_outerConHdr.setHeader(i_vaddr);
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck> outer setheader failed");
+ break;
+ }
if (!l_outerConHdr.sb_flags()->hw_key_transition)
{
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck() - Key transition flag not set");
@@ -1290,7 +1313,14 @@ errlHndl_t SPnorRP::keyTransitionCheck(const uint8_t *i_vaddr) const
// Validate nested container is properly signed using new hw keys
uint8_t * l_nestedVaddr = const_cast<uint8_t*>(i_vaddr) + PAGESIZE;
- SECUREBOOT::ContainerHeader l_nestedConHdr(l_nestedVaddr);
+ SECUREBOOT::ContainerHeader l_nestedConHdr;
+ l_errl = l_nestedConHdr.setHeader(l_nestedVaddr);
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck> nested setheader failed");
+ break;
+ }
+
l_errl = SECUREBOOT::verifyContainer(l_nestedVaddr,
l_nestedConHdr.hwKeyHash());
if (l_errl)
@@ -1298,6 +1328,7 @@ errlHndl_t SPnorRP::keyTransitionCheck(const uint8_t *i_vaddr) const
TRACFCOMP( g_trac_pnor, ERR_MRK"SPnorRP::keyTransitionCheck() - failed verifyContainer");
break;
}
+
}while(0);
return l_errl;
diff --git a/src/usr/runtime/preverifiedlidmgr.C b/src/usr/runtime/preverifiedlidmgr.C
index 62671860f..b63d565f5 100644
--- a/src/usr/runtime/preverifiedlidmgr.C
+++ b/src/usr/runtime/preverifiedlidmgr.C
@@ -434,8 +434,13 @@ errlHndl_t PreVerifiedLidMgr::loadImage(const uint64_t i_imgAddr,
if(cv_addFakeHdrs)
{
TRACDCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage fake header load");
- SECUREBOOT::ContainerHeader l_fakeHdr(i_imgSize,
- SectionIdToString(cv_curPnorSecId));
+ SECUREBOOT::ContainerHeader l_fakeHdr;
+ l_errl = l_fakeHdr.setFakeHeader(i_imgSize,
+ PNOR::SectionIdToString(cv_curPnorSecId));
+ if(l_errl)
+ {
+ break;
+ }
// Inject Fake header into reserved memory
memcpy(reinterpret_cast<void*>(l_tmpVaddr),
l_fakeHdr.fakeHeader(),
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index bb23872d7..ffb957cfb 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -5779,7 +5779,13 @@ errlHndl_t secureKeyTransition()
// Get new verified HW key hash
const void* l_pVaddr = reinterpret_cast<void*>(l_secInfo.vaddr);
- SECUREBOOT::ContainerHeader l_nestedConHdr(l_pVaddr);
+ SECUREBOOT::ContainerHeader l_nestedConHdr;
+ l_errl = l_nestedConHdr.setHeader(l_pVaddr);
+ if(l_errl)
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK"secureKeyTransition() - setheader failed");
+ break;
+ }
// Get pointer to first element of hwKeyHash from header.
const uint8_t* l_hwKeyHash = l_nestedConHdr.hwKeyHash()[0];
// Update global variable with hw keys hash to transition to.
diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H
index 1355cc75d..590258ec0 100644
--- a/src/usr/secureboot/base/test/securerommgrtest.H
+++ b/src/usr/secureboot/base/test/securerommgrtest.H
@@ -244,7 +244,14 @@ class SecureRomManagerTest : public CxxTest::TestSuite
/*******************************************************************/
/* Parse Secure Container Header */
/*******************************************************************/
- SECUREBOOT::ContainerHeader l_conHdr(signedFile_pageAddr);
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errl = l_conHdr.setHeader(signedFile_pageAddr);
+ if (l_errl)
+ {
+ TS_FAIL("SecureRomManagerTest::test_parse_container_header: failed to parse Container Header");
+ errlCommit(l_errl, SECURE_COMP_ID);
+ break;
+ }
// Check if container header seems valid
if (!l_conHdr.iv_isValid)
@@ -321,7 +328,14 @@ class SecureRomManagerTest : public CxxTest::TestSuite
/* Parse Secure Container Header */
/*******************************************************************/
- SECUREBOOT::ContainerHeader l_conHdr(signedFile_pageAddr);
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errl = l_conHdr.setHeader(signedFile_pageAddr);
+ if (l_errl)
+ {
+ TS_FAIL("SecureRomManagerTest::test_hash_page_table_verify: failed to parse Container Header");
+ errlCommit(l_errl, SECURE_COMP_ID);
+ break;
+ }
size_t l_payloadTextSize = l_conHdr.payloadTextSize();
TRACUCOMP(g_trac_secure, "SecureRomManagerTest::test_hash_page_table_verify ContainerHeader payload_size = 0x%X",
l_payloadTextSize);
@@ -447,6 +461,8 @@ class SecureRomManagerTest : public CxxTest::TestSuite
break;
}
+ // Could replace with SECUREBOOT::ContainerHeader ability to generate
+ // fake headers
char pHeader[MAX_SECURE_HEADER_SIZE]={0};
memcpy(pHeader,signedFile_pageAddr,sizeof(pHeader));
@@ -462,7 +478,15 @@ class SecureRomManagerTest : public CxxTest::TestSuite
{
memset(pCompIdInContainer,0x00,compIdSize);
strncpy(pCompIdInContainer,test.pActualCompId,compIdSize);
- SECUREBOOT::ContainerHeader containerHeader(pHeader);
+ SECUREBOOT::ContainerHeader containerHeader;
+ pError = containerHeader.setHeader(pHeader);
+ if (pError)
+ {
+ errlCommit(pError, SECURE_COMP_ID);
+ TS_FAIL("SecureRomManagerTest::test_verifyContainer: failed to parse Container Header");
+ break;
+ }
+
pError = SECUREBOOT::verifyComponent(
containerHeader,
@@ -536,20 +560,24 @@ class SecureRomManagerTest : public CxxTest::TestSuite
// otherwise strncmp below needs a different size
const char* l_compId = "FAKEHEADERTEST";
+ do {
// Simple call constructor to create fake header and make sure it
// does not cause an error
- SECUREBOOT::ContainerHeader l_fakeHdr(l_totalContainerSize, l_compId);
-
- // Check if Header is mising
- if (!PNOR::cmpSecurebootMagicNumber(l_fakeHdr.fakeHeader()))
+ SECUREBOOT::ContainerHeader l_fakeHdr;
+ errlHndl_t l_errl = l_fakeHdr.setFakeHeader(l_totalContainerSize,
+ l_compId);
+ if (l_errl)
{
- TS_FAIL("SecureRomManagerTest::test_fakeHeader: missing magic number");
+ TS_FAIL("SecureRomManagerTest::test_fakeHeader: failed to parse Container Header");
+ errlCommit(l_errl, SECURE_COMP_ID);
+ break;
}
// Payload Text Size should be the total container size minus the header
if(l_fakeHdr.payloadTextSize() != (l_totalContainerSize - PAGE_SIZE))
{
TS_FAIL("SecureRomManagerTest::test_fakeHeader: payload text size was not parsed correctly");
+ break;
}
// Ensure the parsed component ID matches what was passed in through
@@ -558,7 +586,9 @@ class SecureRomManagerTest : public CxxTest::TestSuite
SW_HDR_COMP_ID_SIZE_BYTES) != 0)
{
TS_FAIL("SecureRomManagerTest::test_fakeHeader: component ID was not parsed correctly");
+ break;
}
+ } while(0);
}
};
diff --git a/src/usr/secureboot/common/containerheader.C b/src/usr/secureboot/common/containerheader.C
index dd43551d2..cec5f8cce 100644
--- a/src/usr/secureboot/common/containerheader.C
+++ b/src/usr/secureboot/common/containerheader.C
@@ -24,6 +24,8 @@
/* IBM_PROLOG_END_TAG */
#include <secureboot/containerheader.H>
#include "../common/securetrace.H"
+#include <secureboot/secure_reasoncodes.H>
+#include <pnor/pnor_reasoncodes.H>
// Quick change for unit testing
//#define TRACUCOMP(args...) TRACFCOMP(args)
@@ -32,52 +34,111 @@
namespace SECUREBOOT
{
-void ContainerHeader::parse_header(const void* i_header)
+errlHndl_t ContainerHeader::parse_header()
{
- assert(i_header != nullptr);
- const uint8_t* l_hdr = reinterpret_cast<const uint8_t*>(i_header);
+ assert(iv_pHdrStart != nullptr, "Cannot parse header that is nullptr");
+ const uint8_t* l_hdr = reinterpret_cast<const uint8_t*>(iv_pHdrStart);
+ errlHndl_t l_errl = nullptr;
+
+ do {
/*---- Parse ROM_container_raw ----*/
// The rom code has a placeholder for the prefix in the first struct
size_t l_size = offsetof(ROM_container_raw, prefix);
- safeMemCpyAndInc(&iv_headerInfo.hw_hdr, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.hw_hdr, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
// Early check if magic number is valid, as a quick check to try and prevent
// any storage exceptions while parsing header.
- assert(iv_headerInfo.hw_hdr.magic_number == ROM_MAGIC_NUMBER,
- "ContainerHeader: magic number = 0x%08X not valid",
- iv_headerInfo.hw_hdr.magic_number);
+ if(iv_headerInfo.hw_hdr.magic_number != ROM_MAGIC_NUMBER)
+ {
+ TRACFCOMP(g_trac_secure,ERR_MRK"ContainerHeader::parse_header() Magic Number = 0x%X not valid to parse Container Header",
+ iv_headerInfo.hw_hdr.magic_number);
+
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SECUREBOOT::MOD_SECURE_CONT_HDR_PARSE
+ * @reasoncode PNOR::RC_BAD_SECURE_MAGIC_NUM
+ * @userdata1 Actual magic number
+ * @userdata2 Expected magic number
+ * @devdesc Error parsing secure header
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SECUREBOOT::MOD_SECURE_CONT_HDR_PARSE,
+ PNOR::RC_BAD_SECURE_MAGIC_NUM,
+ iv_headerInfo.hw_hdr.magic_number,
+ ROM_MAGIC_NUMBER,
+ true/*SW Error*/);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ break;
+ }
/*---- Parse ROM_prefix_header_raw ----*/
l_size = offsetof(ROM_prefix_header_raw, ecid);
- safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
// Get ECID array
l_size = iv_headerInfo.hw_prefix_hdr.ecid_count * ECID_SIZE;
- safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr.ecid, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.hw_prefix_hdr.ecid, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
/*---- Parse ROM_prefix_data_raw ----*/
l_size = offsetof(ROM_prefix_data_raw, sw_pkey_p);
- safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
// Get SW keys
l_size = iv_headerInfo.hw_prefix_hdr.sw_key_count * sizeof(ecc_key_t);
// Cache total software keys size
iv_totalSwKeysSize = l_size;
- safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data.sw_pkey_p, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.hw_prefix_data.sw_pkey_p, l_hdr,
+ l_size);
+ if(l_errl)
+ {
+ break;
+ }
/*---- Parse ROM_sw_header_raw ----*/
l_size = offsetof(ROM_sw_header_raw, ecid);
- safeMemCpyAndInc(&iv_headerInfo.sw_hdr, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.sw_hdr, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
strncpy(iv_componentId,iv_headerInfo.sw_hdr.component_id,
sizeof(iv_headerInfo.sw_hdr.component_id));
// Get ECID array
l_size = iv_headerInfo.sw_hdr.ecid_count * ECID_SIZE;
- safeMemCpyAndInc(&iv_headerInfo.sw_hdr.ecid, l_hdr, l_size);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.sw_hdr.ecid, l_hdr, l_size);
+ if(l_errl)
+ {
+ break;
+ }
/*---- Parse ROM_sw_sig_raw ----*/
- safeMemCpyAndInc(&iv_headerInfo.sw_sig.sw_sig_p, l_hdr, iv_totalSwKeysSize);
+ l_errl = safeMemCpyAndInc(&iv_headerInfo.sw_sig.sw_sig_p, l_hdr,
+ iv_totalSwKeysSize);
+ if(l_errl)
+ {
+ break;
+ }
// Parse hw and sw flags
parseFlags();
@@ -88,10 +149,18 @@ void ContainerHeader::parse_header(const void* i_header)
#endif
// After parsing check if header is valid, do some quick bound checks
- validate();
+ l_errl = validate();
+ if(l_errl)
+ {
+ break;
+ }
// Debug printing
print();
+
+ } while(0);
+
+ return l_errl;
}
void ContainerHeader::initVars()
@@ -153,7 +222,6 @@ void ContainerHeader::genFakeHeader(const size_t i_totalSize,
// No-op already zeroed out
iv_pHdrStart = reinterpret_cast<const uint8_t*>(iv_fakeHeader.data());
- parse_header(iv_fakeHeader.data());
}
void ContainerHeader::print() const
@@ -264,8 +332,10 @@ const SHA512_t* ContainerHeader::hwKeyHash() const
return &iv_hwKeyHash;
}
-void ContainerHeader::validate()
+errlHndl_t ContainerHeader::validate()
{
+ errlHndl_t l_errl = nullptr;
+
iv_isValid = (iv_hdrBytesRead <= MAX_SECURE_HEADER_SIZE)
&& (iv_headerInfo.hw_hdr.magic_number == ROM_MAGIC_NUMBER)
&& (iv_headerInfo.hw_hdr.version == ROM_VERSION)
@@ -275,24 +345,85 @@ void ContainerHeader::validate()
&& (iv_headerInfo.hw_prefix_hdr.sw_key_count >= SW_KEY_COUNT_MIN)
&& (iv_headerInfo.hw_prefix_hdr.sw_key_count <= SW_KEY_COUNT_MAX)
&& (iv_headerInfo.sw_hdr.payload_size != 0);
+
+ if(!iv_isValid)
+ {
+ TRACFCOMP(g_trac_secure,ERR_MRK"ContainerHeader::validate() failed weak header verification");
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SECUREBOOT::MOD_SECURE_CONT_VALIDATE
+ * @reasoncode SECUREBOOT::RC_CONT_HDR_INVALID
+ * @userdata1[0::31] Magic Number
+ * @userdata1[32::63] ROM version
+ * @userdata2[0:15] Algorithm version
+ * @userdata2[16:31] Hash algorithm
+ * @userdata2[32:47] Signature algorithm
+ * @userdata2[48:63] SW key count
+ * @devdesc Error parsing secure header
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SECUREBOOT::MOD_SECURE_CONT_VALIDATE,
+ SECUREBOOT::RC_CONT_HDR_INVALID,
+ TWO_UINT32_TO_UINT64(iv_headerInfo.hw_hdr.magic_number,
+ iv_headerInfo.hw_hdr.version),
+ FOUR_UINT16_TO_UINT64(iv_headerInfo.hw_prefix_hdr.ver_alg.version,
+ iv_headerInfo.hw_prefix_hdr.ver_alg.hash_alg,
+ iv_headerInfo.hw_prefix_hdr.ver_alg.sig_alg,
+ iv_headerInfo.hw_prefix_hdr.sw_key_count),
+ true/*SW Error*/);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ }
+
+ return l_errl;
}
-void ContainerHeader::safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
+errlHndl_t ContainerHeader::safeMemCpyAndInc(void* i_dest, const uint8_t* &io_hdr,
const size_t i_size)
{
- assert(i_dest != nullptr, "ContainerHeader: dest ptr NULL");
- assert(io_hdr != nullptr, "ContainerHeader: current header location ptr NULL");
- assert(iv_pHdrStart != nullptr, "ContainerHeader: start of header ptr NULL");
+ assert(i_dest != nullptr, "ContainerHeader: dest nullptr");
+ assert(io_hdr != nullptr, "ContainerHeader: current header location nullptr");
+ assert(iv_pHdrStart != nullptr, "ContainerHeader: start of header nullptr");
TRACDCOMP(g_trac_secure,"dest: 0x%X src: 0x%X size: 0x%X",i_dest, io_hdr, i_size);
+ errlHndl_t l_errl = nullptr;
+ do {
// Determine if the memcpy is within the bounds of the container header
iv_hdrBytesRead = io_hdr - iv_pHdrStart;
- assert( (iv_hdrBytesRead + i_size) <= MAX_SECURE_HEADER_SIZE,
- "ContainerHeader: memcpy is out of bounds of max header size");
+ if((iv_hdrBytesRead + i_size) > MAX_SECURE_HEADER_SIZE)
+ {
+ TRACFCOMP(g_trac_secure,ERR_MRK"ContainerHeader::safeMemCpyAndInc parsed header is out of bounds of max header size of 0x%X",
+ MAX_SECURE_HEADER_SIZE);
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid SECUREBOOT::MOD_SECURE_CONT_HDR_CPY_INC
+ * @reasoncode SECUREBOOT::RC_CONT_HDR_NO_SPACE
+ * @userdata1 Size needed
+ * @userdata2 Max secure header size
+ * @devdesc Error parsing secure header
+ * @custdesc Firmware Error
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ SECUREBOOT::MOD_SECURE_CONT_HDR_CPY_INC,
+ SECUREBOOT::RC_CONT_HDR_NO_SPACE,
+ iv_hdrBytesRead + i_size,
+ MAX_SECURE_HEADER_SIZE,
+ true/*SW Error*/);
+ l_errl->collectTrace(SECURE_COMP_NAME);
+ l_errl->collectTrace(PNOR_COMP_NAME);
+ break;
+ }
memcpy(i_dest, io_hdr, i_size);
io_hdr += i_size;
+
+ } while(0);
+
+ return l_errl;
}
bool ContainerHeader::isValid() const
@@ -333,4 +464,22 @@ const uint8_t* ContainerHeader::fakeHeader() const
return iv_fakeHeader.data();
}
+errlHndl_t ContainerHeader::setHeader(const void* i_header)
+{
+ assert(i_header != nullptr, "Cannot set header to nullptr");
+ iv_pHdrStart = reinterpret_cast<const uint8_t*>(i_header);
+ initVars();
+ return parse_header();
+}
+
+
+errlHndl_t ContainerHeader::setFakeHeader(const size_t i_totalSize,
+ const char* i_compId)
+{
+ initVars();
+ genFakeHeader(i_totalSize, i_compId);
+ return parse_header();
+}
+
+
}; //end of SECUREBOOT namespace
diff --git a/src/usr/secureboot/trusted/base/trustedboot_base.C b/src/usr/secureboot/trusted/base/trustedboot_base.C
index 806ecd91e..b94484bb8 100644
--- a/src/usr/secureboot/trusted/base/trustedboot_base.C
+++ b/src/usr/secureboot/trusted/base/trustedboot_base.C
@@ -445,7 +445,13 @@ errlHndl_t extendBaseImage()
}
// Build a container header object from the raw header
- const SECUREBOOT::ContainerHeader hbbContainerHeader(pHbbHeader);
+ SECUREBOOT::ContainerHeader hbbContainerHeader;
+ pError = hbbContainerHeader.setHeader(pHbbHeader);
+ if (pError)
+ {
+ TRACFCOMP(g_trac_trustedboot, ERR_MRK"extendBaseImage() setheader failed");
+ break;
+ }
const void* pHbbVa = nullptr;
if(!SECUREBOOT::enabled())
diff --git a/src/usr/util/runtime/utillidmgr_rt.C b/src/usr/util/runtime/utillidmgr_rt.C
index 0e45de3f0..05f15c3c4 100644
--- a/src/usr/util/runtime/utillidmgr_rt.C
+++ b/src/usr/util/runtime/utillidmgr_rt.C
@@ -163,44 +163,18 @@ errlHndl_t UtilLidMgr::loadLid()
{
UTIL_FT("UtilLidMgr::loadLid - resv mem section found");
- // Ensure Section has a Secure Header
- if (!PNOR::cmpSecurebootMagicNumber(
- reinterpret_cast<uint8_t*>(iv_lidBuffer)))
+ // Build a container header object to parse protected size
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errl = l_conHdr.setHeader(iv_lidBuffer);
+ if (l_errl)
{
- UTIL_FT(ERR_MRK"UtilLidMgr::loadLid: currently don't support "
- "a reserved memory area without a secure header. Section = %s",
- PNOR::SectionIdToString(pnorSectionId));
-
- uint64_t l_actualBytes = 0;
- memcpy(&l_actualBytes,
- iv_lidBuffer,
- sizeof(ROM_MAGIC_NUMBER));
-
- /*@
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid Util::UTIL_LIDMGR_RT
- * @reasoncode PNOR::RC_BAD_SECURE_MAGIC_NUM
- * @userdata1 Section attempting to be loaded
- * @userdata2 First 4 bytes of vaddr
- * @devdesc Error loading lid from reserved memory without secure header
- * @custdesc Firmware Error
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- Util::UTIL_LIDMGR_RT,
- PNOR::RC_BAD_SECURE_MAGIC_NUM,
- pnorSectionId,
- l_actualBytes,
- true/*SW Error*/);
+ UTIL_FT(ERR_MRK"UtilLidMgr::loadLid - setheader failed");
break;
}
+ iv_lidSize = l_conHdr.payloadTextSize();
UTIL_FT("UtilLidMgr::loadLid - resv mem section has secure header");
- // Build a container header object to parse protected size
- SECUREBOOT::ContainerHeader l_conHdr(iv_lidBuffer);
- iv_lidSize = l_conHdr.payloadTextSize();
-
// Increment by page size to not expose secure header
iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) +
PAGESIZE;
diff --git a/src/usr/util/utilmclmgr.C b/src/usr/util/utilmclmgr.C
index d3974a5e3..66c3b1a29 100644
--- a/src/usr/util/utilmclmgr.C
+++ b/src/usr/util/utilmclmgr.C
@@ -619,7 +619,13 @@ errlHndl_t MasterContainerLidMgr::verifyExtend(const ComponentID& i_compId,
}
// Parse Container Header
- SECUREBOOT::ContainerHeader l_conHdr(iv_pVaddr);
+ SECUREBOOT::ContainerHeader l_conHdr;
+ l_errl = l_conHdr.setHeader(iv_pVaddr);
+ if (l_errl)
+ {
+ UTIL_FT(ERR_MRK"MasterContainerLidMgr::verifyExtend - setheader failed");
+ break;
+ }
// Cache size stats into comp info cache
io_compInfo.totalSize = l_conHdr.totalContainerSize();
OpenPOWER on IntegriCloud