diff options
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/isteps/istep14/call_mss_power_cleanup.C | 4 | ||||
-rw-r--r-- | src/usr/isteps/makefile | 2 | ||||
-rw-r--r-- | src/usr/isteps/nvdimm/nvdimm.C | 180 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types.xml | 66 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/target_types.xml | 9 |
5 files changed, 258 insertions, 3 deletions
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> |