summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2019-03-27 14:10:44 -0400
committerDan Williams <dan.j.williams@intel.com>2019-03-30 11:26:37 -0400
commit037c8489ade669e0f09ad40d5b91e5e1159a14b1 (patch)
tree34bc6ee6b1449b9567ea64e228cd038a980df58f
parent486fa92df4707b5df58d6508728bdb9321a59766 (diff)
libnvdimm/security: provide fix for secure-erase to use zero-key
Add a zero key in order to standardize hardware that want a key of 0's to be passed. Some platforms defaults to a zero-key with security enabled rather than allow the OS to enable the security. The zero key would allow us to manage those platform as well. This also adds a fix to secure erase so it can use the zero key to do crypto erase. Some other security commands already use zero keys. This introduces a standard zero-key to allow unification of semantics cross nvdimm security commands. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/security.c17
-rw-r--r--tools/testing/nvdimm/test/nfit.c11
2 files changed, 21 insertions, 7 deletions
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..6bea6852bf27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -22,6 +22,8 @@ static bool key_revalidate = true;
22module_param(key_revalidate, bool, 0444); 22module_param(key_revalidate, bool, 0444);
23MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); 23MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
24 24
25static const char zero_key[NVDIMM_PASSPHRASE_LEN];
26
25static void *key_data(struct key *key) 27static void *key_data(struct key *key)
26{ 28{
27 struct encrypted_key_payload *epayload = dereference_key_locked(key); 29 struct encrypted_key_payload *epayload = dereference_key_locked(key);
@@ -286,8 +288,9 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
286{ 288{
287 struct device *dev = &nvdimm->dev; 289 struct device *dev = &nvdimm->dev;
288 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 290 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
289 struct key *key; 291 struct key *key = NULL;
290 int rc; 292 int rc;
293 const void *data;
291 294
292 /* The bus lock should be held at the top level of the call stack */ 295 /* The bus lock should be held at the top level of the call stack */
293 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); 296 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
319 return -EOPNOTSUPP; 322 return -EOPNOTSUPP;
320 } 323 }
321 324
322 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 325 if (keyid != 0) {
323 if (!key) 326 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
324 return -ENOKEY; 327 if (!key)
328 return -ENOKEY;
329 data = key_data(key);
330 } else
331 data = zero_key;
325 332
326 rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type); 333 rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type);
327 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key), 334 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
328 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", 335 pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
329 rc == 0 ? "success" : "fail"); 336 rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..cad719876ef4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
225 225
226static struct gen_pool *nfit_pool; 226static struct gen_pool *nfit_pool;
227 227
228static const char zero_key[NVDIMM_PASSPHRASE_LEN];
229
228static struct nfit_test *to_nfit_test(struct device *dev) 230static struct nfit_test *to_nfit_test(struct device *dev)
229{ 231{
230 struct platform_device *pdev = to_platform_device(dev); 232 struct platform_device *pdev = to_platform_device(dev);
@@ -1059,8 +1061,7 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t,
1059 struct device *dev = &t->pdev.dev; 1061 struct device *dev = &t->pdev.dev;
1060 struct nfit_test_sec *sec = &dimm_sec_info[dimm]; 1062 struct nfit_test_sec *sec = &dimm_sec_info[dimm];
1061 1063
1062 if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) || 1064 if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
1063 (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
1064 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE; 1065 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
1065 dev_dbg(dev, "secure erase: wrong security state\n"); 1066 dev_dbg(dev, "secure erase: wrong security state\n");
1066 } else if (memcmp(nd_cmd->passphrase, sec->passphrase, 1067 } else if (memcmp(nd_cmd->passphrase, sec->passphrase,
@@ -1068,6 +1069,12 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t,
1068 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS; 1069 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
1069 dev_dbg(dev, "secure erase: wrong passphrase\n"); 1070 dev_dbg(dev, "secure erase: wrong passphrase\n");
1070 } else { 1071 } else {
1072 if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED)
1073 && (memcmp(nd_cmd->passphrase, zero_key,
1074 ND_INTEL_PASSPHRASE_SIZE) != 0)) {
1075 dev_dbg(dev, "invalid zero key\n");
1076 return 0;
1077 }
1071 memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1078 memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
1072 memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1079 memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
1073 sec->state = 0; 1080 sec->state = 0;