diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/usr/secureboot/containerheader.H | 78 | ||||
-rw-r--r-- | src/include/usr/secureboot/secure_reasoncodes.H | 5 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 35 | ||||
-rw-r--r-- | src/usr/pnor/spnorrp.C | 39 | ||||
-rw-r--r-- | src/usr/runtime/preverifiedlidmgr.C | 9 | ||||
-rw-r--r-- | src/usr/sbe/sbe_update.C | 8 | ||||
-rw-r--r-- | src/usr/secureboot/base/test/securerommgrtest.H | 46 | ||||
-rw-r--r-- | src/usr/secureboot/common/containerheader.C | 195 | ||||
-rw-r--r-- | src/usr/secureboot/trusted/base/trustedboot_base.C | 8 | ||||
-rw-r--r-- | src/usr/util/runtime/utillidmgr_rt.C | 38 | ||||
-rw-r--r-- | src/usr/util/utilmclmgr.C | 8 |
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(); |