summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCorey Swenson <cswenson@us.ibm.com>2019-04-17 15:57:46 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-05-11 19:44:57 -0500
commit06d0a08aa27fa9e28cc300fbd2814fd9b84d59cf (patch)
tree71c1ca09bb7b2896d1d01aeb65d0a91a0285f548 /src
parentfa1b266a6293e69f6a67d392d272f90623c28111 (diff)
downloadtalos-hostboot-06d0a08aa27fa9e28cc300fbd2814fd9b84d59cf.tar.gz
talos-hostboot-06d0a08aa27fa9e28cc300fbd2814fd9b84d59cf.zip
Add NVDIMM key attributes and generate keys
3 keys, 32 bytes each, random numbers generated by TPM hardware. 2 attributes for keys, 1 stored in FW 1 stored in anchor card. 1 attribute for enable/disable encryption. Change-Id: Ie3c258f06204e68c2d65b8d5fea294da5264d597 RTC:208342 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/76126 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimm.H11
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H5
-rw-r--r--src/usr/isteps/istep14/call_mss_power_cleanup.C4
-rw-r--r--src/usr/isteps/makefile2
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C180
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml66
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml9
7 files changed, 273 insertions, 4 deletions
diff --git a/src/include/usr/isteps/nvdimm/nvdimm.H b/src/include/usr/isteps/nvdimm/nvdimm.H
index 567299925..864ef187f 100644
--- a/src/include/usr/isteps/nvdimm/nvdimm.H
+++ b/src/include/usr/isteps/nvdimm/nvdimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -73,6 +73,15 @@ bool nvdimm_update(TARGETING::TargetHandleList &i_nvdimmList);
/**
+ * @brief Entry function to NVDIMM generate keys
+ * Generate encryption keys if required and set the FW key attribute
+ *
+ * @param[in] i_nvdimmList - list of nvdimm targets
+ *
+ */
+void nvdimm_gen_keys(TARGETING::TargetHandleList &i_nvdimmList);
+
+/**
* @brief This function erases image on the nvdimm target
*
* @param[in] i_nvdimm - nvdimm target with NV controller
diff --git a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
index 0b1680d92..f84581896 100644
--- a/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
+++ b/src/include/usr/isteps/nvdimm/nvdimmreasoncodes.H
@@ -85,6 +85,8 @@ enum nvdimmModuleId
VALIDATE_FW_IMAGE = 0x23,
WAIT_FW_OPS_BLOCK_RECEIVED = 0x24,
NVDIMM_IS_UPDATE_NEEDED = 0x25,
+ NVDIMM_RUN_UPDATE_USING_LID = 0x26,
+ NVDIMM_GEN_KEYS = 0x27,
};
/**
@@ -135,6 +137,9 @@ enum nvdimmReasonCode
NVDIMM_BLOCK_NOT_RECEIVED = NVDIMM_COMP_ID | 0x25, // Block data not received
NVDIMM_FW_OPS_NOT_SUCCESSFUL = NVDIMM_COMP_ID | 0x26, // Unsuccessful Firmware Operation
NVDIMM_UPDATE_NOT_SUPPORTED = NVDIMM_COMP_ID | 0x27, // NV controller cannot be updated
+ NVDIMM_START_UPDATE = NVDIMM_COMP_ID | 0x28, // start update
+ NVDIMM_UPDATE_COMPLETE = NVDIMM_COMP_ID | 0x29, // update completed
+ NVDIMM_TPM_NOT_FOUND = NVDIMM_COMP_ID | 0x30, // TPM not found
};
enum UserDetailsTypes
diff --git a/src/usr/isteps/istep14/call_mss_power_cleanup.C b/src/usr/isteps/istep14/call_mss_power_cleanup.C
index 3ca963678..c86d172be 100644
--- a/src/usr/isteps/istep14/call_mss_power_cleanup.C
+++ b/src/usr/isteps/istep14/call_mss_power_cleanup.C
@@ -129,8 +129,10 @@ void* call_mss_power_cleanup (void *io_pArgs)
}
}
- // Run the nvdimm management function if the list is not empty
+ // Run the nvdimm management functions if the list is not empty
if (!l_nvdimmTargetList.empty()){
+ // Must generate encryption keys before the restore
+ NVDIMM::nvdimm_gen_keys(l_nvdimmTargetList);
NVDIMM::nvdimm_restore(l_nvdimmTargetList);
}
}
diff --git a/src/usr/isteps/makefile b/src/usr/isteps/makefile
index 496861bf2..5a53e3291 100644
--- a/src/usr/isteps/makefile
+++ b/src/usr/isteps/makefile
@@ -50,7 +50,7 @@ SUBDIRS+=tod.d
SUBDIRS+=fab_iovalid.d
SUBDIRS+=nest.d
SUBDIRS+=io.d
-SUBDIRS+=nvdimm.d
+SUBDIRS+=$(if $(CONFIG_NVDIMM),nvdimm.d)
SUBDIRS+=ucd.d
SUBDIRS+=expupd.d
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index 79d7b679d..50bcfebfb 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -41,6 +41,7 @@
#include <isteps/nvdimm/nvdimmreasoncodes.H>
#include <isteps/nvdimm/nvdimm.H>
#include <vpd/spdenums.H>
+#include <secureboot/trustedbootif.H>
using namespace TARGETING;
using namespace DeviceFW;
@@ -63,7 +64,6 @@ namespace NVDIMM
#define NVDIMM_SET_USER_DATA_2_TIMEOUT(left_32_polled, right_32_timeout) \
NVDIMM_SET_USER_DATA_1(left_32_polled, right_32_timeout)
-
typedef struct ops_timeoutInfo{
const char * desc;
uint16_t offset[2];
@@ -83,6 +83,9 @@ constexpr ops_timeoutInfo_t timeoutInfoTable[] =
{"CHARGE", {ES_CHARGE_TIMEOUT1, ES_CHARGE_TIMEOUT0}, CHARGE , MODULE_HEALTH_STATUS1, CHARGE_IN_PROGRESS},
};
+const size_t NUM_KEYS_IN_ATTR = 3;
+const size_t MAX_KEY_SIZE = 32;
+
/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
*
@@ -1451,6 +1454,181 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
}
/**
+ * @brief Entry function to NVDIMM generate keys
+ * Generate encryption keys if required and set the FW key attribute
+ */
+void nvdimm_gen_keys(TargetHandleList &i_nvdimmList)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_gen_keys()");
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Determine if key generation required
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_gen_keys: no TopLevelTarget");
+
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
+ {
+ break;
+ }
+
+ // Get the FW attribute
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type l_attrKeysFw = {0};
+ assert(l_sys->tryGetAttr
+ <ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw),
+ "nvdimm_gen_keys() Failed getting ATTR_NVDIMM_ENCRYPTION_KEYS_FW");
+
+ // FW attribute checks
+ size_t l_attrSizeFw = sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type);
+ // Attribute size must be a multiple of the key size
+ assert((l_attrSizeFw % NUM_KEYS_IN_ATTR) == 0,
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_FW is not a multiple of the key size");
+ // Attribute key size must not exceed max size
+ assert((l_attrSizeFw / NUM_KEYS_IN_ATTR) <= MAX_KEY_SIZE,
+ "nvdimm_gen_keys() Size of keys in ATTR_NVDIMM_ENCRYPTION_KEYS_FW is greater than MAX_KEY_SIZE");
+
+ // Check for FW attribute = zero
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type l_fwCompare = {0};
+ bool l_attrIsZeroFw = memcmp(l_attrKeysFw, l_fwCompare, l_attrSizeFw) == 0;
+
+ // Get the anchor attribute
+ ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type l_attrKeysAnchor = {0};
+ assert(l_sys->tryGetAttr
+ <ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR>(l_attrKeysAnchor),
+ "nvdimm_gen_keys() Failed getting ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+
+ // Anchor attribute checks
+ size_t l_attrSizeAnchor = sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type);
+ // Attribute size must be a multiple of the key size
+ assert((l_attrSizeAnchor % NUM_KEYS_IN_ATTR) == 0,
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR is not a multiple of the key size");
+ // Attribute key size must not exceed max size
+ assert((l_attrSizeAnchor / NUM_KEYS_IN_ATTR) <= MAX_KEY_SIZE,
+ "nvdimm_gen_keys() Size of keys in ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR is greater than MAX_KEY_SIZE");
+
+ // Check for Anchor attribute = zero
+ ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type l_anchorCompare = {0};
+ bool l_attrIsZeroAnchor = memcmp(l_attrKeysAnchor, l_anchorCompare, l_attrSizeAnchor) == 0;
+
+ // Compare the attribute values
+ if (!l_attrIsZeroFw && !l_attrIsZeroAnchor)
+ {
+ if (memcmp(l_attrKeysFw,l_attrKeysAnchor,l_attrSizeFw) == 0)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW = ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ }
+ if (memcmp(l_attrKeysFw,l_attrKeysAnchor,l_attrSizeFw) != 0)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ }
+ break;
+ }
+ if (!l_attrIsZeroFw && l_attrIsZeroAnchor)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != 0 and ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR = 0");
+ break;
+ }
+ if (l_attrIsZeroFw && !l_attrIsZeroAnchor)
+ {
+ // Set FW attr = Anchor attr
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() Setting ATTR_NVDIMM_ENCRYPTION_KEYS_FW = ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysAnchor);
+ break;
+ }
+
+ // Both key attributes are zero
+ // Generate random keys using the TPM hardware
+ TargetHandleList l_tpmList;
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_FUNCTIONAL);
+ if (l_tpmList.size() == 0)
+ {
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"No functional TPM found, encryption keys not generated.");
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_TPM_NOT_FOUND
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_GEN_KEYS
+ *@userdata1 <UNUSED>
+ *@userdata2 <UNUSED>
+ *@devdesc Encountered error generating NVDIMM encryption keys
+ *@custdesc NVDIMM error generating encryption keys
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_GEN_KEYS,
+ NVDIMM_TPM_NOT_FOUND,
+ 0x0,
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+
+ // Get all TPMs
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);
+ if (l_tpmList.size() == 0)
+ {
+ // No TPMs, we probably have nvdimms enabled
+ // when they should not be
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ else
+ {
+ // If a TPM exists it must be deconfigured,
+ // add callouts accordingly
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_FIND_DECONFIGURED_PART,
+ HWAS::SRCI_PRIORITY_HIGH);
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+ }
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+
+ // Set the status flag for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ }
+
+ break;
+ }
+
+
+ // TPM can only generate up to 34 bytes so gen 1 key at a time
+ size_t l_genSize = l_attrSizeFw / NUM_KEYS_IN_ATTR;
+ uint8_t l_genData[l_genSize] = {0};
+ for (uint32_t l_key=0; l_key<NUM_KEYS_IN_ATTR; l_key++)
+ {
+ l_err = TRUSTEDBOOT::GetRandom(l_tpmList[0], l_genSize, l_genData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_gen_keys() Failing Trustedboot::GetRandom()");
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ memcpy(
+ reinterpret_cast<uint8_t*>(l_attrKeysFw) + (l_key*l_genSize),
+ l_genData,
+ l_genSize );
+ }
+
+ // Set the FW attribute
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw);
+
+ }while(0);
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_gen_keys()");
+}
+
+/**
* @brief NVDIMM initialization
* - Checks for ready state
* - Gathers timeout values
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 2378f270e..0101d2f16 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -5111,6 +5111,72 @@
</attribute>
<attribute>
+ <id>NVDIMM_ENCRYPTION_ENABLE</id>
+ <description>
+ 0 - Encryption is not enabled on all NVDIMMS in the system
+ 1 - Encryption is enabled on all NVDIMMS in the system
+ </description>
+ <simpleType>
+ <uint8_t>
+ <default>1</default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_ANCHOR</id>
+ <description>
+ NVDIMM Encryption keys
+ Bytes 0..31 Random String (RS)
+ Bytes 32..63 Erase Key (EK)
+ Bytes 64..95 Access Key (AK)
+ Set by HWSV, stored in anchor card
+ Should match NVDIMM_ENCRYPTION_KEYS_FW
+ </description>
+ <simpleType>
+ <array>96</array>
+ <uint8_t>
+ <default>
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ </default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_FW</id>
+ <description>
+ NVDIMM Encryption keys
+ Bytes 0..31 Random String (RS)
+ Bytes 32..63 Erase Key (EK)
+ Bytes 64..95 Access Key (AK)
+ Set by Hostboot, stored in FSP flash
+ Should match NVDIMM_ENCRYPTION_KEYS_ANCHOR
+ </description>
+ <simpleType>
+ <array>96</array>
+ <uint8_t>
+ <default>
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ </default>
+ </uint8_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<id>NV_OPS_TIMEOUT_MSEC</id>
<description>
NVDIMM timeout value for 6 main operations
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index e5d7b9bd7..c04afc747 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -2037,6 +2037,15 @@
<id>NUMERIC_POD_TYPE_TEST</id>
</attribute>
<attribute>
+ <id>NVDIMM_ENCRYPTION_ENABLE</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_ANCHOR</id>
+ </attribute>
+ <attribute>
+ <id>NVDIMM_ENCRYPTION_KEYS_FW</id>
+ </attribute>
+ <attribute>
<id>O_EREPAIR_THRESHOLD_FIELD</id>
</attribute>
<attribute>
OpenPOWER on IntegriCloud