summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2017-10-20 21:13:34 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-11-03 09:45:20 -0400
commit07d75753d59419ea6ba9ee3bd930e0aa8e7e7fd5 (patch)
tree78633da60312ff8cfd54807f787219036e976621 /src/usr
parent47f275a6bd3b2104a82d9786122afd6fe25f05de (diff)
downloadtalos-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>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/errl/errludstring.C56
-rw-r--r--src/usr/errl/plugins/errludparserfactoryerrl.H11
-rw-r--r--src/usr/errl/plugins/errludstring.H104
-rw-r--r--src/usr/pnor/spnorrp.C11
-rw-r--r--src/usr/scom/plugins/errludP_scom.H14
-rw-r--r--src/usr/scom/plugins/scomUdParserFactory.H18
-rw-r--r--src/usr/secureboot/base/securerommgr.C59
-rw-r--r--src/usr/secureboot/base/test/securerommgrtest.H129
8 files changed, 384 insertions, 18 deletions
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);
+ }
+ }
};
/**********************************************************************/
OpenPOWER on IntegriCloud