diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2017-10-20 21:13:34 -0500 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2017-11-03 09:45:20 -0400 |
commit | 07d75753d59419ea6ba9ee3bd930e0aa8e7e7fd5 (patch) | |
tree | 78633da60312ff8cfd54807f787219036e976621 | |
parent | 47f275a6bd3b2104a82d9786122afd6fe25f05de (diff) | |
download | talos-hostboot-07d75753d59419ea6ba9ee3bd930e0aa8e7e7fd5.tar.gz talos-hostboot-07d75753d59419ea6ba9ee3bd930e0aa8e7e7fd5.zip |
Secure Boot: Enforce PNOR section component IDs
- In secure mode, bootloader will enforce that HBB component ID is set
- In secure mode, Hostboot will enforce that PNOR component IDs are set
Change-Id: I04f3bbc45417b3229003c56e1083e1fc31c01cd7
RTC: 179422
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48711
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
-rw-r--r-- | src/bootloader/bootloader.C | 87 | ||||
-rw-r--r-- | src/build/debug/Hostboot/BlTrace.pm | 2 | ||||
-rw-r--r-- | src/include/bootloader/bootloader_trace.H | 6 | ||||
-rw-r--r-- | src/include/bootloader/hbblreasoncodes.H | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | src/include/string.h | 3 | ||||
-rw-r--r-- | src/include/usr/errl/errlreasoncodes.H | 9 | ||||
-rw-r--r-- | src/include/usr/errl/errludstring.H | 62 | ||||
-rw-r--r-- | src/include/usr/secureboot/secure_reasoncodes.H | 1 | ||||
-rw-r--r-- | src/include/usr/secureboot/service.H | 20 | ||||
-rw-r--r-- | src/lib/string.C | 22 | ||||
-rw-r--r-- | src/lib/string_utils.C | 59 | ||||
-rw-r--r-- | src/usr/errl/errludstring.C | 56 | ||||
-rw-r--r-- | src/usr/errl/plugins/errludparserfactoryerrl.H | 11 | ||||
-rw-r--r-- | src/usr/errl/plugins/errludstring.H | 104 | ||||
-rw-r--r-- | src/usr/pnor/spnorrp.C | 11 | ||||
-rw-r--r-- | src/usr/scom/plugins/errludP_scom.H | 14 | ||||
-rw-r--r-- | src/usr/scom/plugins/scomUdParserFactory.H | 18 | ||||
-rw-r--r-- | src/usr/secureboot/base/securerommgr.C | 59 | ||||
-rw-r--r-- | src/usr/secureboot/base/test/securerommgrtest.H | 129 |
19 files changed, 625 insertions, 49 deletions
diff --git a/src/bootloader/bootloader.C b/src/bootloader/bootloader.C index 99ac0b1ec..745e33c5d 100644 --- a/src/bootloader/bootloader.C +++ b/src/bootloader/bootloader.C @@ -178,6 +178,89 @@ namespace Bootloader{ } /** + * @brief Verify container's component ID against a reference + * component ID. Up to 8 ASCII characters, not including NULL, will be + * compared (thus, it is critical that all components are unique with + * respect to the first 8 bytes). + * + * @param[in] i_pHeader Void pointer to start of the container's secure + * header. Must not be nullptr or function will assert. + * @param[in] i_pComponentId Reference component ID to compare to. Must + * not be nullptr or function will assert. + */ + void verifyComponent( + const void* const i_pHeader, + const char* const i_pComponentId) + { + assert(i_pHeader != nullptr); + assert(i_pComponentId != nullptr); + + const auto* const pHwPrefix = + reinterpret_cast<const ROM_prefix_header_raw* const>( + reinterpret_cast<const uint8_t* const>(i_pHeader) + + offsetof(ROM_container_raw,prefix)); + const auto swKeyCount = pHwPrefix->sw_key_count; + const auto ecidCount = pHwPrefix->ecid_count; + + const char* const pCompIdInContainer = + reinterpret_cast<const char* const>(i_pHeader) + + offsetof(ROM_container_raw,prefix) + + offsetof(ROM_prefix_header_raw,ecid) + + ecidCount*ECID_SIZE + + offsetof(ROM_prefix_data_raw,sw_pkey_p) + + swKeyCount*sizeof(ecc_key_t) + + offsetof(ROM_sw_header_raw,component_id); + + if(strncmp(pCompIdInContainer, + i_pComponentId, + sizeof(ROM_sw_header_raw::component_id)) != 0) + { + char pTruncatedComponentId[ + sizeof(ROM_sw_header_raw::component_id) + + sizeof(uint8_t)]={0}; + strncpy(pTruncatedComponentId, + i_pComponentId, + sizeof(ROM_sw_header_raw::component_id)); + + BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_FAILED); + + // Read SBE HB shared data + const auto pBlConfigData = reinterpret_cast< + BootloaderConfigData_t *>(SBE_HB_COMM_ADDR); + + /*@ + * @errortype + * @moduleid Bootloader::MOD_BOOTLOADER_VERIFY_COMP_ID + * @reasoncode SECUREBOOT::RC_ROM_VERIFY + * @userdata1[0:15] TI_WITH_SRC + * @userdata1[16:31] TI_BOOTLOADER + * @userdata1[32:63] Failing address = 0 + * @userdata2[0:31] First 4 bytes of observed component ID + * @userdata2[32:63] Last 4 bytes of observed component ID + * @errorInfo[0:15] SBE boot side + * @errorInfo[16:31] Unused + * @devdesc Container component ID verification failed. + * @custdesc Platform security violation detected + */ + bl_terminate( + MOD_BOOTLOADER_VERIFY_COMP_ID, + SECUREBOOT::RC_ROM_VERIFY, + *reinterpret_cast<const uint32_t*>( + pCompIdInContainer), + *reinterpret_cast<const uint32_t*>( + pCompIdInContainer+sizeof(uint32_t)), + true, + 0, + TWO_UINT16_TO_UINT32( + pBlConfigData->sbeBootSide,0)); + } + else + { + BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_SUCCESS); + } + } + + /** * @brief Verify Container against system hash keys * * @param[in] i_pContainer Void pointer to effective address @@ -298,11 +381,13 @@ namespace Bootloader{ } BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_SUCCESS); + + verifyComponent(i_pContainer, + PNOR::SectionIdToString(PNOR::HB_BASE_CODE)); } #endif } - /** Bootloader main function to work with and start HBB. * * @return 0. diff --git a/src/build/debug/Hostboot/BlTrace.pm b/src/build/debug/Hostboot/BlTrace.pm index c285ec03d..3d4476e7c 100644 --- a/src/build/debug/Hostboot/BlTrace.pm +++ b/src/build/debug/Hostboot/BlTrace.pm @@ -41,6 +41,8 @@ my %traceText = ( # @TODO RTC:167740 TI on failed magic # check once signing is widespread "18" => "Main verify skip verification - no magic number ", "19" => "Main verify skip verification - SAB unset ", + "1A" => "Main verify component ID succeeded", + "1B" => "Main verify component ID failed", "20" => "HandleMMIO started", "21" => "HandleMMIO started using BYTESIZE", "24" => "HandleMMIO started using WORDSIZE", diff --git a/src/include/bootloader/bootloader_trace.H b/src/include/bootloader/bootloader_trace.H index 129b9a303..3b3fa262a 100644 --- a/src/include/bootloader/bootloader_trace.H +++ b/src/include/bootloader/bootloader_trace.H @@ -77,6 +77,12 @@ enum BootloaderTraces /** Bootloader main verifyContainer skip verification - SAB unset */ BTLDR_TRC_MAIN_VERIFY_SAB_UNSET = 0x19, + /** Bootloader main verifyComponent succeeded */ + BTLDR_TRC_COMP_ID_VERIFY_SUCCESS = 0x1A, + + /** Bootloader main verifyComponent failed */ + BTLDR_TRC_COMP_ID_VERIFY_FAILED = 0x1B, + /** Bootloader handleMMIO started */ BTLDR_TRC_HANDLEMMIO_START = 0x20, diff --git a/src/include/bootloader/hbblreasoncodes.H b/src/include/bootloader/hbblreasoncodes.H index 392b7e4b3..1a4dbc98f 100644 --- a/src/include/bootloader/hbblreasoncodes.H +++ b/src/include/bootloader/hbblreasoncodes.H @@ -49,6 +49,7 @@ namespace Bootloader MOD_PNORACC_GETHBBSECT = 0x04, /**< bl_pnorAccess.C : get HBB sect */ MOD_BOOTLOADER_VERIFY = 0x05, /**< bootloader.C : verifyContainer */ MOD_BOOTLOADER_ASSERT = 0x06, /**< bootloader.H assert */ + MOD_BOOTLOADER_VERIFY_COMP_ID = 0x07, /**< bootloader.C : verifyComponent */ }; /** diff --git a/src/include/string.h b/src/include/string.h index 589507c06..ca1a0ba4c 100755..100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2010,2014 */ +/* Contributors Listed Below - COPYRIGHT 2010,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -42,6 +42,7 @@ extern "C" char* strcpy(char* d, const char* s); char* strncpy(char* d, const char* s, size_t l); int strcmp(const char* s1, const char* s2) __attribute__((pure)); + int strncmp(const char* s1, const char* s2, size_t l) __attribute__((pure)); size_t strlen(const char* s1) __attribute__((pure)); size_t strnlen(const char* s1, size_t n) __attribute__((pure)); diff --git a/src/include/usr/errl/errlreasoncodes.H b/src/include/usr/errl/errlreasoncodes.H index 1e7f2ea77..f9d03c246 100644 --- a/src/include/usr/errl/errlreasoncodes.H +++ b/src/include/usr/errl/errlreasoncodes.H @@ -62,7 +62,7 @@ namespace ERRORLOG ERRL_LAST_ERR = ERRL_COMP_ID | 0xFF }; - // Identifiers for ERRL user data sections. + // Identifiers for ERRL user data subsections. enum errlUserDetailDataSubsection { ERRL_UDT_NOFORMAT = 0x00, @@ -74,6 +74,13 @@ namespace ERRORLOG ERRL_UDT_CALLOUT = 0x06, ERRL_UDT_PRINTK = 0x07, ERRL_UDT_SENSOR = 0x08, + ERRL_UDT_STRING_SET = 0x09, + }; + + // Identifiers for ERRL user data subsection versions + enum errlUserDetailDataSubsectionVersion + { + ERRL_UDT_STRING_SET_VER_1 = 0x01, }; }; diff --git a/src/include/usr/errl/errludstring.H b/src/include/usr/errl/errludstring.H index f8e4cd3d7..c3d8ecdee 100644 --- a/src/include/usr/errl/errludstring.H +++ b/src/include/usr/errl/errludstring.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -57,10 +59,60 @@ public: */ virtual ~ErrlUserDetailsString(); -private: - // Disabled - ErrlUserDetailsString(const ErrlUserDetailsString &); - ErrlUserDetailsString & operator=(const ErrlUserDetailsString &); + private: + + // Disable compiler provided default functions + ErrlUserDetailsString( + const ErrlUserDetailsString &); + ErrlUserDetailsString & operator=( + const ErrlUserDetailsString &); + ErrlUserDetailsString ( + ErrlUserDetailsString&&) = delete; + ErrlUserDetailsString& operator = ( + ErrlUserDetailsString&&) = delete; +}; + +/** + * @class ErrlUserDetailsStringSet + * + * @brief Adds multiple, tagged FFDC strings to an error log as user details + * data + */ +class ErrlUserDetailsStringSet : public ErrlUserDetails +{ + + public: + + /** + * @brief Constructor; creates the object + */ + ErrlUserDetailsStringSet(); + + /** + * @brief Adds a new tagged string to the object's string cache + * + * @param[in] i_pDescriptionString Description of the string to add. Must + * not be nullptr or function will substitute an error message. + * @param[in] i_pString The string to add. Must not be nullptr or function + * will substitute an error message. + */ + void add(const char* i_pDescriptionString, + const char* i_pString); + + /** + * @brief Destructor + */ + virtual ~ErrlUserDetailsStringSet(); + + // Disable compiler provided default functions + ErrlUserDetailsStringSet( + const ErrlUserDetailsStringSet&) = delete; + ErrlUserDetailsStringSet& operator=( + const ErrlUserDetailsStringSet&) = delete; + ErrlUserDetailsStringSet ( + ErrlUserDetailsStringSet&&) = delete; + ErrlUserDetailsStringSet& operator = ( + ErrlUserDetailsStringSet&&) = delete; }; } diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H index 98fe38d3c..f633ef7b2 100644 --- a/src/include/usr/secureboot/secure_reasoncodes.H +++ b/src/include/usr/secureboot/secure_reasoncodes.H @@ -40,6 +40,7 @@ namespace SECUREBOOT MOD_SECURE_READ_REG = 0x06, MOD_SECURE_WRITE_REG = 0x07, MOD_SECURE_SETTINGS_INIT = 0x08, + MOD_SECURE_VERIFY_COMPONENT = 0x09, }; enum SECUREReasonCode diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H index 4c4d43d3c..c4dc31334 100644 --- a/src/include/usr/secureboot/service.H +++ b/src/include/usr/secureboot/service.H @@ -58,6 +58,8 @@ typedef uint8_t PAGE_TABLE_ENTRY_t[HASH_PAGE_TABLE_ENTRY_SIZE]; namespace SECUREBOOT { + class ContainerHeader; + /** @brief Perform initialization of Secureboot for the Base image. * * - Copy secure header from original location. @@ -223,6 +225,24 @@ namespace SECUREBOOT const SHA512_t* i_hwKeyHash = nullptr); /** + * @brief Verify component ID in a container header against a reference + * component ID. Up to 8 ASCII characters, not including NULL, will be + * compared (thus, it is critical that all components are unique with + * respect to the first 8 bytes). + * + * @param[in] i_containerHeader Verified container's header + * @param[in] i_pComponentString Reference component ID string; must not be + * nullptr or function will assert. + * + * @return errlHndl_t Error log handle + * @retval nullptr Component ID verification succeeded + * @retval !nullptr Error; component ID verification failed + */ + errlHndl_t verifyComponent( + const ContainerHeader& i_containerHeader, + const char* i_pComponentId); + + /** * @brief Hash Signed Blob * * @param[in] i_blob Void pointer to effective address of blob diff --git a/src/lib/string.C b/src/lib/string.C index 004345372..43e46f6cc 100644 --- a/src/lib/string.C +++ b/src/lib/string.C @@ -78,28 +78,6 @@ extern "C" char* strcpy(char* d, const char* s) } while(1); } -extern "C" char* strncpy(char* d, const char* s, size_t l) -{ - char* d1 = d; - size_t len = 0; - - do - { - if (len++ >= l) break; - *d1 = *s; - if (*s == '\0') break; - d1++; s++; - } while(1); - - // pad the remainder - while( len < l ) - { - d1[len++] = '\0'; - } - - return d; -} - extern "C" int strcmp(const char* a, const char* b) { while((*a != '\0') && (*b != '\0')) diff --git a/src/lib/string_utils.C b/src/lib/string_utils.C index 79a8bf709..27d9228fb 100644 --- a/src/lib/string_utils.C +++ b/src/lib/string_utils.C @@ -120,4 +120,61 @@ extern "C" int memcmp(const void *p1, const void *p2, size_t len) } return 0; -}
\ No newline at end of file +} + +extern "C" int strncmp(const char* a, const char* b, size_t l) +{ + if(l==0) + { + return 0; + } + + const char* begin=a; + while( (*a != '\0') && (*b != '\0') + && (static_cast<size_t>(a-begin)+1<l) ) + { + if (*a == *b) + { + a++; b++; + } + else + { + return (*a > *b) ? 1 : -1; + } + } + if (*a == *b) + { + return 0; + } + if (*a == '\0') + { + return -1; + } + else + { + return 1; + } +} + +extern "C" char* strncpy(char* d, const char* s, size_t l) +{ + char* d1 = d; + size_t len = 0; + + do + { + if (len++ >= l) break; + *d1 = *s; + if (*s == '\0') break; + d1++; s++; + } while(1); + + // pad the remainder + while( len < l ) + { + d1[len++] = '\0'; + } + + return d; +} + diff --git a/src/usr/errl/errludstring.C b/src/usr/errl/errludstring.C index 43943774d..888a303b6 100644 --- a/src/usr/errl/errludstring.C +++ b/src/usr/errl/errludstring.C @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -54,5 +56,57 @@ ErrlUserDetailsString::~ErrlUserDetailsString() } +// ErrlUserDetailsStringSet implementation + +ErrlUserDetailsStringSet::ErrlUserDetailsStringSet() +{ + // Set up ErrlUserDetails instance variables + iv_CompId = ERRL_COMP_ID; + iv_Version = ERRL_UDT_STRING_SET_VER_1; + iv_SubSection = ERRL_UDT_STRING_SET; + + // override the default of false. + iv_merge = true; } +void ErrlUserDetailsStringSet::add( + const char* const i_pDescriptionString, + const char* const i_pString) +{ + // [Object Memory Layout] + // + // Offset Size Description + // ========================================================================= + // 0 X Existing object contents before this call, where X=0 if + // this is the first add call to the object + // X Y NULL terminated description string describing the string + // being logged, where Y=strlen(this string) + length (1) of + // NULL terminator. + // X+Y Z NULL terminated FFDC string, where Z=strlen(this string) + + // length (1) of NULL terminator. + + // Absorb API errors on error path and instead substitue error string for + // any input that is nullptr + const char* const pDescriptionString = (i_pDescriptionString == nullptr) ? + "BUG! Invalid description" : i_pDescriptionString; + const char* const pString = (i_pString == nullptr) ? "BUG! Invalid string" : + i_pString; + + const auto currentSize = static_cast<size_t>(getUsrBufSize()); + const auto descriptionSize = strlen(pDescriptionString)+1; + const auto stringSize = strlen(pString)+1; + const auto newSize = currentSize + descriptionSize + stringSize; + char* const pBuf = reinterpret_cast<char*>( + reallocUsrBuf(newSize)); + strcpy(pBuf+currentSize, pDescriptionString); + strcpy(pBuf+currentSize+descriptionSize,pString); +} + +ErrlUserDetailsStringSet::~ErrlUserDetailsStringSet() +{ + +} + +} // End of ERRORLOG namespace + + diff --git a/src/usr/errl/plugins/errludparserfactoryerrl.H b/src/usr/errl/plugins/errludparserfactoryerrl.H index 1db49a8dc..ebe7acb47 100644 --- a/src/usr/errl/plugins/errludparserfactoryerrl.H +++ b/src/usr/errl/plugins/errludparserfactoryerrl.H @@ -58,6 +58,7 @@ public: ErrlUserDetailsParserFactoryErrl() { registerParser<ErrlUserDetailsParserString>(ERRL_UDT_STRING); + registerParser<ErrlUserDetailsParserStringSet>(ERRL_UDT_STRING_SET); registerParser<ErrlUserDetailsParserTarget>(ERRL_UDT_TARGET); registerParser<ErrlUserDetailsParserBackTrace>(ERRL_UDT_BACKTRACE); registerParser<ErrlUserDetailsParserAttribute>(ERRL_UDT_ATTRIBUTE); @@ -68,10 +69,16 @@ public: private: - // Disabled - ErrlUserDetailsParserFactoryErrl(const ErrlUserDetailsParserFactoryErrl &); + // Parser isn't compiled with c++11 in all environments, and therefore + // "delete" of unused interfaces (like below) is not supported, nor are + // functions with move semantics + + // Disable compiler provided default functions + ErrlUserDetailsParserFactoryErrl( + const ErrlUserDetailsParserFactoryErrl &); ErrlUserDetailsParserFactoryErrl & operator=( const ErrlUserDetailsParserFactoryErrl &); + }; } diff --git a/src/usr/errl/plugins/errludstring.H b/src/usr/errl/plugins/errludstring.H index 51f91d5f8..9fbd185f1 100644 --- a/src/usr/errl/plugins/errludstring.H +++ b/src/usr/errl/plugins/errludstring.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] International Business Machines Corp. */ +/* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ @@ -79,14 +81,106 @@ public: } } -private: - // Disabled - ErrlUserDetailsParserString(const ErrlUserDetailsParserString &); + private: + + // Parser isn't compiled with c++11 in all environments, and therefore + // "delete" of unused interfaces (like below) is not supported, nor are + // functions with move semantics + + // Disable compiler provided default functions + ErrlUserDetailsParserString( + const ErrlUserDetailsParserString &); ErrlUserDetailsParserString & operator=( const ErrlUserDetailsParserString &); + +}; + +/** + * @class ErrlUserDetailsParserStringSet + * + * Parses string set user details from an error log + */ +class ErrlUserDetailsParserStringSet : public ErrlUserDetailsParser +{ + + public: + + /** + * @brief Constructor + */ + ErrlUserDetailsParserStringSet() + { + } + + /** + * @brief Destructor + */ + virtual ~ErrlUserDetailsParserStringSet() + { + } + + /** + * @brief Parses string set user details data from an error log + * + * @param i_version Version of the data + * @param i_parse ErrlUsrParser object for outputting information + * @param i_pBuffer Pointer to buffer containing detail data + * @param i_buflen Length of the buffer + */ + virtual void parse( + errlver_t i_version, + ErrlUsrParser& i_parser, + void* i_pBuffer, + const uint32_t i_buflen) const + { + // [Input Buffer Memory Layout] + // + // The input buffer contains N sequentially packed pairs of variable + // length, NULL terminated strings, where each string pair is also + // sequentially packed and the sum of the lengths of all such pairs + // exactly equals the input buffer length. Each string pair is + // formatted as below, beginning from either the start of the buffer or + // the end of the previous string pair: + // + // Offset Size Description + // ===================================================================== + // 0 Y NULL terminated description string describing the + // significance of the string to follow, Y=strlen(this + // string) + length (1) of NULL terminator. + // Y Z NULL terminated FFDC string, where Z=strlen(this + // string) + length (1) of NULL terminator. + + const char* pBuf = static_cast<const char*>(i_pBuffer); + const size_t len = static_cast<size_t>(i_buflen); + const char* pBufEnd = pBuf + len; + while(pBuf < pBufEnd) + { + const size_t descriptionStringSize = strlen(pBuf) + 1; + const char* const pDescriptionString = pBuf; + pBuf += descriptionStringSize; + + const size_t stringSize = strlen(pBuf) + 1; + const char* const pString = pBuf; + pBuf += stringSize; + + i_parser.PrintString(pDescriptionString,pString); + } + } + + private: + + // Parser isn't compiled with c++11 in all environments, and therefore + // "delete" of unused interfaces (like below) is not supported, nor are + // functions with move semantics + + // Disable compiler provided default functions + ErrlUserDetailsParserStringSet( + const ErrlUserDetailsParserStringSet&); + ErrlUserDetailsParserStringSet & operator=( + const ErrlUserDetailsParserStringSet&); }; -} +} // End ERRLOG namespace #endif diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C index 78453f59c..1643215fd 100644 --- a/src/usr/pnor/spnorrp.C +++ b/src/usr/pnor/spnorrp.C @@ -465,6 +465,17 @@ uint64_t SPnorRP::verifySections(SectionId i_id, failedVerify = true; break; } + + auto const * const pPnorString = PNOR::SectionIdToString(i_id); + l_errhdl = SECUREBOOT::verifyComponent(l_conHdr,pPnorString); + if(l_errhdl) + { + TRACFCOMP(g_trac_pnor, ERR_MRK"SPnorrRP::verifySections: " + "Failed in call to SECUREBOOT::verifyComponent"); + failedVerify = true; + break; + } + l_errhdl = miscSectionVerification(l_tempAddr, i_id); if (l_errhdl) { diff --git a/src/usr/scom/plugins/errludP_scom.H b/src/usr/scom/plugins/errludP_scom.H index f3a704cf6..c8201f9fa 100644 --- a/src/usr/scom/plugins/errludP_scom.H +++ b/src/usr/scom/plugins/errludP_scom.H @@ -98,9 +98,17 @@ namespace SCOM i_parser.PrintString("Pib Err", l_outputStr ); } - // Disabled - UdParserPib(const UdParserPib&) = delete; - UdParserPib & operator=(const UdParserPib&) = delete; + private: + + // Parser isn't compiled with c++11 in all environments, and + // therefore "delete" of unused interfaces (like below) is not + // supported, nor are functions with move semantics + + // Disable compiler provided default functions + UdParserPib( + const UdParserPib&); + UdParserPib & operator=( + const UdParserPib&); }; } diff --git a/src/usr/scom/plugins/scomUdParserFactory.H b/src/usr/scom/plugins/scomUdParserFactory.H index d8ff3ceef..2763e0f32 100644 --- a/src/usr/scom/plugins/scomUdParserFactory.H +++ b/src/usr/scom/plugins/scomUdParserFactory.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -40,10 +40,18 @@ namespace SCOM (SCOM_UDT_PIB); } - //Disabled - UserDetailsParserFactory(const UserDetailsParserFactory &) = delete; - UserDetailsParserFactory & operator= - (const UserDetailsParserFactory &) = delete; + + private: + + // Parser isn't compiled with c++11 in all environments, and + // therefore "delete" of unused interfaces (like below) is not + // supported, nor are functions with move semantics + + // Disable compiler provided default functions + UserDetailsParserFactory( + const UserDetailsParserFactory &); + UserDetailsParserFactory & operator= ( + const UserDetailsParserFactory &); }; }; diff --git a/src/usr/secureboot/base/securerommgr.C b/src/usr/secureboot/base/securerommgr.C index 072fcf950..7e517c31d 100644 --- a/src/usr/secureboot/base/securerommgr.C +++ b/src/usr/secureboot/base/securerommgr.C @@ -34,12 +34,14 @@ #include <errl/errlmanager.H> #include "../common/securetrace.H" #include <kernel/bltohbdatamgr.H> +#include <errl/errludstring.H> +#include <string.h> #include "securerommgr.H" #include <secureboot/settings.H> #include <config.h> #include <console/consoleif.H> -#include <array> +#include <secureboot/containerheader.H> // Quick change for unit testing //#define TRACUCOMP(args...) TRACFCOMP(args) @@ -85,6 +87,61 @@ errlHndl_t verifyContainer(void * i_container, const SHA512_t* i_hwKeyHash) return l_errl; } +errlHndl_t verifyComponent( + const ContainerHeader& i_containerHeader, + const char* const i_pComponentId) +{ + assert(i_pComponentId != nullptr,"BUG! Component ID string was nullptr"); + + errlHndl_t pError = nullptr; + + if(strncmp(i_containerHeader.componentId(), + i_pComponentId, + sizeof(ROM_sw_header_raw::component_id)) != 0) + { + char pTruncatedComponentId[sizeof(ROM_sw_header_raw::component_id)+ + sizeof(uint8_t)]={0}; + strncpy(pTruncatedComponentId, + i_pComponentId, + sizeof(ROM_sw_header_raw::component_id)); + + TRACFCOMP(g_trac_secure,ERR_MRK"SECUREROM::verifyComponent: " + "Secure Boot verification failure; container's component ID of " + "[%s] does not match expected component ID of [%s] (truncated " + "from [%s]", + i_containerHeader.componentId(), + pTruncatedComponentId, + i_pComponentId); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_VERIFY_COMPONENT + * @reasoncode SECUREBOOT::RC_ROM_VERIFY + * @devdesc Container's component ID does not match expected + * component ID + * @custdesc Secure Boot firmware validation failed + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_VERIFY_COMPONENT, + SECUREBOOT::RC_ROM_VERIFY, + 0, + 0, + true /*Add HB Software Callout*/ ); + + ERRORLOG::ErrlUserDetailsStringSet stringSet; + stringSet.add("Actual component ID",i_containerHeader.componentId()); + stringSet.add("Expected ID (truncated)",pTruncatedComponentId); + stringSet.add("Expected ID (full)",i_pComponentId); + stringSet.addToLog(pError); + + pError->collectTrace(SECURE_COMP_NAME,ERROR_TRACE_SIZE); + } + + return pError; +} + /** * @brief Hash Signed Blob * diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H index 7db0dc2cc..4a445b52f 100644 --- a/src/usr/secureboot/base/test/securerommgrtest.H +++ b/src/usr/secureboot/base/test/securerommgrtest.H @@ -25,7 +25,7 @@ #ifndef __SECUREROMMANAGERTEST_H #define __SECUREROMMANAGERTEST_H - +#include <array> #include <sys/mm.h> #include <sys/mmio.h> #include <vfs/vfs.H> @@ -35,6 +35,7 @@ #include <secureboot/service.H> #include <secureboot/secure_reasoncodes.H> #include <kernel/bltohbdatamgr.H> +#include <stddef.h> #include "../securerommgr.H" @@ -398,6 +399,132 @@ class SecureRomManagerTest : public CxxTest::TestSuite TRACFCOMP(g_trac_secure,EXIT_MRK"SecureRomManagerTest::test_hash_page_table_verify"); } + void test_verifyComponent(void) + { + errlHndl_t pError = nullptr; + + // Signed file variables + const char* signedFile_name = "secureboot_signed_container"; + void* signedFile_pageAddr = nullptr; + size_t signedFile_size = 0; + uint64_t signedFile_vaddr = 0; + + do { + + struct verifyComponentTest + { + const char* pActualCompId; + const char* pRefCompId; + bool shouldPass; + }; + + const std::vector<verifyComponentTest> tests = + { {"ABCD1234","ABCD12345", true }, + {"ABCD1234","ABCD1234" , true }, + {"ABCD1234","ABCD123" , false}, + {"ABCD123" ,"ABCD12345", false}, + {"ABCD123" ,"ABCD1234" , false}, + {"ABCD123" ,"ABCD123" , true }, + {"A" ,"A" , true }, + {"A" ,"B" , false}, + {"A" ,"AB" , false}, + {"A" ,"" , false}, + {"" ,"A" , false}, + {"" ,"" , true } }; + + // Call utility function + pError = loadSignedFile( signedFile_name, + signedFile_pageAddr, + signedFile_size, + signedFile_vaddr); + + if (pError) + { + TS_FAIL("SecureRomManagerTest::test_verifyComponent: " + "loadSignedFile() Failed"); + errlCommit(pError, SECURE_COMP_ID); + break; + } + + char pHeader[MAX_SECURE_HEADER_SIZE]={0}; + memcpy(pHeader,signedFile_pageAddr,sizeof(pHeader)); + + char* const pCompIdInContainer = pHeader + + offsetof(ROM_container_raw,prefix) + + offsetof(ROM_prefix_header_raw,ecid) + + offsetof(ROM_prefix_data_raw,sw_pkey_q) + + offsetof(ROM_sw_header_raw,component_id); + + const size_t compIdSize = sizeof(ROM_sw_header_raw::component_id); + + for(const auto& test : tests) + { + memset(pCompIdInContainer,0x00,compIdSize); + strncpy(pCompIdInContainer,test.pActualCompId,compIdSize); + SECUREBOOT::ContainerHeader containerHeader(pHeader); + + pError = SECUREBOOT::verifyComponent( + containerHeader, + test.pRefCompId); + if(pError) + { + if(test.shouldPass) + { + TS_FAIL("SecureRomManagerTest::test_verifyContainer: " + "Expected SECUREBOOT::verifyComponent to pass, but it " + "failed. Actual component ID was [%s], reference " + "component ID was [%s]", + test.pActualCompId, + test.pRefCompId); + errlCommit(pError, SECURE_COMP_ID); + } + else // Should fail + { + // But verify it's the right fail + if( ( pError->reasonCode() + != SECUREBOOT::RC_ROM_VERIFY) + || ( pError->moduleId() + != SECUREBOOT::MOD_SECURE_VERIFY_COMPONENT)) + { + TS_FAIL("SecureRomManagerTest::test_verifyContainer: " + "Expected SECUREBOOT::verifyComponent to fail with " + "reason code of 0x%04X and module ID of 0x%02, but " + "failed with reason code of 0x%04X and module ID " + "of 0x%02X. Actual component ID was [%s], " + "reference component ID was [%s]", + SECUREBOOT::RC_ROM_VERIFY, + SECUREBOOT::MOD_SECURE_VERIFY_COMPONENT, + pError->reasonCode(), + pError->moduleId(), + test.pActualCompId, + test.pRefCompId); + errlCommit(pError, SECURE_COMP_ID); + } + else + { + delete pError; + pError = nullptr; + } + } + } + else if(!test.shouldPass) + { + TS_FAIL("SecureRomManagerTest::test_verifyContainer: " + "Expected SECUREBOOT::verifyComponent to fail, but it " + "passed. Actual component ID was [%s], reference " + "component ID was [%s]", + test.pActualCompId, + test.pRefCompId); + } + } + + } while(0); + + if ( signedFile_pageAddr != nullptr ) + { + unloadSignedFile( signedFile_pageAddr, signedFile_size); + } + } }; /**********************************************************************/ |