diff options
author | Dave Jiang <dave.jiang@intel.com> | 2019-03-27 14:10:44 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2019-03-30 11:26:37 -0400 |
commit | 037c8489ade669e0f09ad40d5b91e5e1159a14b1 (patch) | |
tree | 34bc6ee6b1449b9567ea64e228cd038a980df58f | |
parent | 486fa92df4707b5df58d6508728bdb9321a59766 (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.c | 17 | ||||
-rw-r--r-- | tools/testing/nvdimm/test/nfit.c | 11 |
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; | |||
22 | module_param(key_revalidate, bool, 0444); | 22 | module_param(key_revalidate, bool, 0444); |
23 | MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); | 23 | MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); |
24 | 24 | ||
25 | static const char zero_key[NVDIMM_PASSPHRASE_LEN]; | ||
26 | |||
25 | static void *key_data(struct key *key) | 27 | static 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 | ||
226 | static struct gen_pool *nfit_pool; | 226 | static struct gen_pool *nfit_pool; |
227 | 227 | ||
228 | static const char zero_key[NVDIMM_PASSPHRASE_LEN]; | ||
229 | |||
228 | static struct nfit_test *to_nfit_test(struct device *dev) | 230 | static 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; |