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>
This commit is contained in:
parent
486fa92df4
commit
037c8489ad
|
@ -22,6 +22,8 @@ static bool key_revalidate = true;
|
||||||
module_param(key_revalidate, bool, 0444);
|
module_param(key_revalidate, bool, 0444);
|
||||||
MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
|
MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
|
||||||
|
|
||||||
|
static const char zero_key[NVDIMM_PASSPHRASE_LEN];
|
||||||
|
|
||||||
static void *key_data(struct key *key)
|
static void *key_data(struct key *key)
|
||||||
{
|
{
|
||||||
struct encrypted_key_payload *epayload = dereference_key_locked(key);
|
struct encrypted_key_payload *epayload = dereference_key_locked(key);
|
||||||
|
@ -286,8 +288,9 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
|
||||||
{
|
{
|
||||||
struct device *dev = &nvdimm->dev;
|
struct device *dev = &nvdimm->dev;
|
||||||
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
|
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
|
||||||
struct key *key;
|
struct key *key = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
const void *data;
|
||||||
|
|
||||||
/* The bus lock should be held at the top level of the call stack */
|
/* The bus lock should be held at the top level of the call stack */
|
||||||
lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
|
lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
|
||||||
|
@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
|
if (keyid != 0) {
|
||||||
if (!key)
|
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
|
||||||
return -ENOKEY;
|
if (!key)
|
||||||
|
return -ENOKEY;
|
||||||
|
data = key_data(key);
|
||||||
|
} else
|
||||||
|
data = zero_key;
|
||||||
|
|
||||||
rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type);
|
rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type);
|
||||||
dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
|
dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
|
||||||
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
|
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
|
||||||
rc == 0 ? "success" : "fail");
|
rc == 0 ? "success" : "fail");
|
||||||
|
|
|
@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
|
||||||
|
|
||||||
static struct gen_pool *nfit_pool;
|
static struct gen_pool *nfit_pool;
|
||||||
|
|
||||||
|
static const char zero_key[NVDIMM_PASSPHRASE_LEN];
|
||||||
|
|
||||||
static struct nfit_test *to_nfit_test(struct device *dev)
|
static struct nfit_test *to_nfit_test(struct device *dev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
@ -1059,8 +1061,7 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t,
|
||||||
struct device *dev = &t->pdev.dev;
|
struct device *dev = &t->pdev.dev;
|
||||||
struct nfit_test_sec *sec = &dimm_sec_info[dimm];
|
struct nfit_test_sec *sec = &dimm_sec_info[dimm];
|
||||||
|
|
||||||
if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
|
if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
|
||||||
(sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
|
|
||||||
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
|
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
|
||||||
dev_dbg(dev, "secure erase: wrong security state\n");
|
dev_dbg(dev, "secure erase: wrong security state\n");
|
||||||
} else if (memcmp(nd_cmd->passphrase, sec->passphrase,
|
} else if (memcmp(nd_cmd->passphrase, sec->passphrase,
|
||||||
|
@ -1068,6 +1069,12 @@ static int nd_intel_test_cmd_secure_erase(struct nfit_test *t,
|
||||||
nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
|
nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
|
||||||
dev_dbg(dev, "secure erase: wrong passphrase\n");
|
dev_dbg(dev, "secure erase: wrong passphrase\n");
|
||||||
} else {
|
} else {
|
||||||
|
if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED)
|
||||||
|
&& (memcmp(nd_cmd->passphrase, zero_key,
|
||||||
|
ND_INTEL_PASSPHRASE_SIZE) != 0)) {
|
||||||
|
dev_dbg(dev, "invalid zero key\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
|
memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
|
||||||
memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
|
memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
|
||||||
sec->state = 0;
|
sec->state = 0;
|
||||||
|
|
Loading…
Reference in New Issue