aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-12-28 18:05:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-12-28 18:05:13 -0500
commit75f95da078b2891cd186f074ffc15a8e7c3f082d (patch)
tree2ba8da10d0d1e20565e893a777d4349fe9d483dd /drivers
parent4ed7bdc1eb4c82cf4bfdf6a94dd36fd695f6f387 (diff)
parent4b5f747e82b12b6d8ab815fc259827a615c7f2c3 (diff)
Merge tag 'libnvdimm-for-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm updates from Dan Williams: "The vast bulk of this update is the new support for the security capabilities of some nvdimms. The userspace tooling for this capability is still a work in progress, but the changes survive the existing libnvdimm unit tests. The changes also pass manual checkout on hardware and the new nfit_test emulation of the security capability. The touches of the security/keys/ files have received the necessary acks from Mimi and David. Those changes were necessary to allow for a new generic encrypted-key type, and allow the nvdimm sub-system to lookup key material referenced by the libnvdimm-sysfs interface. Summary: - Add support for the security features of nvdimm devices that implement a security model similar to ATA hard drive security. The security model supports locking access to the media at device-power-loss, to be unlocked with a passphrase, and secure-erase (crypto-scramble). Unlike the ATA security case where the kernel expects device security to be managed in a pre-OS environment, the libnvdimm security implementation allows key provisioning and key-operations at OS runtime. Keys are managed with the kernel's encrypted-keys facility to provide data-at-rest security for the libnvdimm key material. The usage model mirrors fscrypt key management, but is driven via libnvdimm sysfs. - Miscellaneous updates for api usage and comment fixes" * tag 'libnvdimm-for-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: (21 commits) libnvdimm/security: Quiet security operations libnvdimm/security: Add documentation for nvdimm security support tools/testing/nvdimm: add Intel DSM 1.8 support for nfit_test tools/testing/nvdimm: Add overwrite support for nfit_test tools/testing/nvdimm: Add test support for Intel nvdimm security DSMs acpi/nfit, libnvdimm/security: add Intel DSM 1.8 master passphrase support acpi/nfit, libnvdimm/security: Add security DSM overwrite support acpi/nfit, libnvdimm: Add support for issue secure erase DSM to Intel nvdimm acpi/nfit, libnvdimm: Add enable/update passphrase support for Intel nvdimms acpi/nfit, libnvdimm: Add disable passphrase support to Intel nvdimm. acpi/nfit, libnvdimm: Add unlock of nvdimm support for Intel DIMMs acpi/nfit, libnvdimm: Add freeze security support to Intel nvdimm acpi/nfit, libnvdimm: Introduce nvdimm_security_ops keys-encrypted: add nvdimm key format type to encrypted keys keys: Export lookup_user_key to external users acpi/nfit, libnvdimm: Store dimm id as a member to struct nvdimm libnvdimm, namespace: Replace kmemdup() with kstrndup() libnvdimm, label: Switch to bitmap_zalloc() ACPI/nfit: Adjust annotation for why return 0 if fail to find NFIT at start libnvdimm, bus: Check id immediately following ida_simple_get ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/nfit/Kconfig11
-rw-r--r--drivers/acpi/nfit/Makefile1
-rw-r--r--drivers/acpi/nfit/core.c103
-rw-r--r--drivers/acpi/nfit/intel.c388
-rw-r--r--drivers/acpi/nfit/intel.h76
-rw-r--r--drivers/acpi/nfit/nfit.h24
-rw-r--r--drivers/nvdimm/Kconfig5
-rw-r--r--drivers/nvdimm/Makefile1
-rw-r--r--drivers/nvdimm/bus.c33
-rw-r--r--drivers/nvdimm/dimm.c16
-rw-r--r--drivers/nvdimm/dimm_devs.c210
-rw-r--r--drivers/nvdimm/label.c7
-rw-r--r--drivers/nvdimm/namespace_devs.c3
-rw-r--r--drivers/nvdimm/nd-core.h57
-rw-r--r--drivers/nvdimm/nd.h8
-rw-r--r--drivers/nvdimm/region_devs.c5
-rw-r--r--drivers/nvdimm/security.c454
17 files changed, 1365 insertions, 37 deletions
diff --git a/drivers/acpi/nfit/Kconfig b/drivers/acpi/nfit/Kconfig
index f7c57e33499e..52eefd732cf2 100644
--- a/drivers/acpi/nfit/Kconfig
+++ b/drivers/acpi/nfit/Kconfig
@@ -13,3 +13,14 @@ config ACPI_NFIT
13 13
14 To compile this driver as a module, choose M here: 14 To compile this driver as a module, choose M here:
15 the module will be called nfit. 15 the module will be called nfit.
16
17config NFIT_SECURITY_DEBUG
18 bool "Enable debug for NVDIMM security commands"
19 depends on ACPI_NFIT
20 help
21 Some NVDIMM devices and controllers support encryption and
22 other security features. The payloads for the commands that
23 enable those features may contain sensitive clear-text
24 security material. Disable debug of those command payloads
25 by default. If you are a kernel developer actively working
26 on NVDIMM security enabling say Y, otherwise say N.
diff --git a/drivers/acpi/nfit/Makefile b/drivers/acpi/nfit/Makefile
index a407e769f103..751081c47886 100644
--- a/drivers/acpi/nfit/Makefile
+++ b/drivers/acpi/nfit/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_ACPI_NFIT) := nfit.o 1obj-$(CONFIG_ACPI_NFIT) := nfit.o
2nfit-y := core.o 2nfit-y := core.o
3nfit-y += intel.o
3nfit-$(CONFIG_X86_MCE) += mce.o 4nfit-$(CONFIG_X86_MCE) += mce.o
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 5912d30020c7..011d3db19c80 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -24,6 +24,7 @@
24#include <linux/nd.h> 24#include <linux/nd.h>
25#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
26#include <acpi/nfit.h> 26#include <acpi/nfit.h>
27#include "intel.h"
27#include "nfit.h" 28#include "nfit.h"
28#include "intel.h" 29#include "intel.h"
29 30
@@ -380,6 +381,16 @@ static u8 nfit_dsm_revid(unsigned family, unsigned func)
380 [NVDIMM_INTEL_QUERY_FWUPDATE] = 2, 381 [NVDIMM_INTEL_QUERY_FWUPDATE] = 2,
381 [NVDIMM_INTEL_SET_THRESHOLD] = 2, 382 [NVDIMM_INTEL_SET_THRESHOLD] = 2,
382 [NVDIMM_INTEL_INJECT_ERROR] = 2, 383 [NVDIMM_INTEL_INJECT_ERROR] = 2,
384 [NVDIMM_INTEL_GET_SECURITY_STATE] = 2,
385 [NVDIMM_INTEL_SET_PASSPHRASE] = 2,
386 [NVDIMM_INTEL_DISABLE_PASSPHRASE] = 2,
387 [NVDIMM_INTEL_UNLOCK_UNIT] = 2,
388 [NVDIMM_INTEL_FREEZE_LOCK] = 2,
389 [NVDIMM_INTEL_SECURE_ERASE] = 2,
390 [NVDIMM_INTEL_OVERWRITE] = 2,
391 [NVDIMM_INTEL_QUERY_OVERWRITE] = 2,
392 [NVDIMM_INTEL_SET_MASTER_PASSPHRASE] = 2,
393 [NVDIMM_INTEL_MASTER_SECURE_ERASE] = 2,
383 }, 394 },
384 }; 395 };
385 u8 id; 396 u8 id;
@@ -394,6 +405,17 @@ static u8 nfit_dsm_revid(unsigned family, unsigned func)
394 return id; 405 return id;
395} 406}
396 407
408static bool payload_dumpable(struct nvdimm *nvdimm, unsigned int func)
409{
410 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
411
412 if (nfit_mem && nfit_mem->family == NVDIMM_FAMILY_INTEL
413 && func >= NVDIMM_INTEL_GET_SECURITY_STATE
414 && func <= NVDIMM_INTEL_MASTER_SECURE_ERASE)
415 return IS_ENABLED(CONFIG_NFIT_SECURITY_DEBUG);
416 return true;
417}
418
397int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, 419int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
398 unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc) 420 unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
399{ 421{
@@ -478,9 +500,10 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
478 500
479 dev_dbg(dev, "%s cmd: %d: func: %d input length: %d\n", 501 dev_dbg(dev, "%s cmd: %d: func: %d input length: %d\n",
480 dimm_name, cmd, func, in_buf.buffer.length); 502 dimm_name, cmd, func, in_buf.buffer.length);
481 print_hex_dump_debug("nvdimm in ", DUMP_PREFIX_OFFSET, 4, 4, 503 if (payload_dumpable(nvdimm, func))
482 in_buf.buffer.pointer, 504 print_hex_dump_debug("nvdimm in ", DUMP_PREFIX_OFFSET, 4, 4,
483 min_t(u32, 256, in_buf.buffer.length), true); 505 in_buf.buffer.pointer,
506 min_t(u32, 256, in_buf.buffer.length), true);
484 507
485 /* call the BIOS, prefer the named methods over _DSM if available */ 508 /* call the BIOS, prefer the named methods over _DSM if available */
486 if (nvdimm && cmd == ND_CMD_GET_CONFIG_SIZE 509 if (nvdimm && cmd == ND_CMD_GET_CONFIG_SIZE
@@ -1573,18 +1596,10 @@ static DEVICE_ATTR_RO(flags);
1573static ssize_t id_show(struct device *dev, 1596static ssize_t id_show(struct device *dev,
1574 struct device_attribute *attr, char *buf) 1597 struct device_attribute *attr, char *buf)
1575{ 1598{
1576 struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev); 1599 struct nvdimm *nvdimm = to_nvdimm(dev);
1600 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
1577 1601
1578 if (dcr->valid_fields & ACPI_NFIT_CONTROL_MFG_INFO_VALID) 1602 return sprintf(buf, "%s\n", nfit_mem->id);
1579 return sprintf(buf, "%04x-%02x-%04x-%08x\n",
1580 be16_to_cpu(dcr->vendor_id),
1581 dcr->manufacturing_location,
1582 be16_to_cpu(dcr->manufacturing_date),
1583 be32_to_cpu(dcr->serial_number));
1584 else
1585 return sprintf(buf, "%04x-%08x\n",
1586 be16_to_cpu(dcr->vendor_id),
1587 be32_to_cpu(dcr->serial_number));
1588} 1603}
1589static DEVICE_ATTR_RO(id); 1604static DEVICE_ATTR_RO(id);
1590 1605
@@ -1780,10 +1795,23 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
1780 const guid_t *guid; 1795 const guid_t *guid;
1781 int i; 1796 int i;
1782 int family = -1; 1797 int family = -1;
1798 struct acpi_nfit_control_region *dcr = nfit_mem->dcr;
1783 1799
1784 /* nfit test assumes 1:1 relationship between commands and dsms */ 1800 /* nfit test assumes 1:1 relationship between commands and dsms */
1785 nfit_mem->dsm_mask = acpi_desc->dimm_cmd_force_en; 1801 nfit_mem->dsm_mask = acpi_desc->dimm_cmd_force_en;
1786 nfit_mem->family = NVDIMM_FAMILY_INTEL; 1802 nfit_mem->family = NVDIMM_FAMILY_INTEL;
1803
1804 if (dcr->valid_fields & ACPI_NFIT_CONTROL_MFG_INFO_VALID)
1805 sprintf(nfit_mem->id, "%04x-%02x-%04x-%08x",
1806 be16_to_cpu(dcr->vendor_id),
1807 dcr->manufacturing_location,
1808 be16_to_cpu(dcr->manufacturing_date),
1809 be32_to_cpu(dcr->serial_number));
1810 else
1811 sprintf(nfit_mem->id, "%04x-%08x",
1812 be16_to_cpu(dcr->vendor_id),
1813 be32_to_cpu(dcr->serial_number));
1814
1787 adev = to_acpi_dev(acpi_desc); 1815 adev = to_acpi_dev(acpi_desc);
1788 if (!adev) { 1816 if (!adev) {
1789 /* unit test case */ 1817 /* unit test case */
@@ -1904,6 +1932,16 @@ static void shutdown_dimm_notify(void *data)
1904 mutex_unlock(&acpi_desc->init_mutex); 1932 mutex_unlock(&acpi_desc->init_mutex);
1905} 1933}
1906 1934
1935static const struct nvdimm_security_ops *acpi_nfit_get_security_ops(int family)
1936{
1937 switch (family) {
1938 case NVDIMM_FAMILY_INTEL:
1939 return intel_security_ops;
1940 default:
1941 return NULL;
1942 }
1943}
1944
1907static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) 1945static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
1908{ 1946{
1909 struct nfit_mem *nfit_mem; 1947 struct nfit_mem *nfit_mem;
@@ -1970,10 +2008,11 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
1970 2008
1971 flush = nfit_mem->nfit_flush ? nfit_mem->nfit_flush->flush 2009 flush = nfit_mem->nfit_flush ? nfit_mem->nfit_flush->flush
1972 : NULL; 2010 : NULL;
1973 nvdimm = nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem, 2011 nvdimm = __nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem,
1974 acpi_nfit_dimm_attribute_groups, 2012 acpi_nfit_dimm_attribute_groups,
1975 flags, cmd_mask, flush ? flush->hint_count : 0, 2013 flags, cmd_mask, flush ? flush->hint_count : 0,
1976 nfit_mem->flush_wpq); 2014 nfit_mem->flush_wpq, &nfit_mem->id[0],
2015 acpi_nfit_get_security_ops(nfit_mem->family));
1977 if (!nvdimm) 2016 if (!nvdimm)
1978 return -ENOMEM; 2017 return -ENOMEM;
1979 2018
@@ -2008,6 +2047,11 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
2008 if (!nvdimm) 2047 if (!nvdimm)
2009 continue; 2048 continue;
2010 2049
2050 rc = nvdimm_security_setup_events(nvdimm);
2051 if (rc < 0)
2052 dev_warn(acpi_desc->dev,
2053 "security event setup failed: %d\n", rc);
2054
2011 nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit"); 2055 nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
2012 if (nfit_kernfs) 2056 if (nfit_kernfs)
2013 nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs, 2057 nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
@@ -3337,7 +3381,7 @@ static int acpi_nfit_flush_probe(struct nvdimm_bus_descriptor *nd_desc)
3337 return 0; 3381 return 0;
3338} 3382}
3339 3383
3340static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc, 3384static int __acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
3341 struct nvdimm *nvdimm, unsigned int cmd) 3385 struct nvdimm *nvdimm, unsigned int cmd)
3342{ 3386{
3343 struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc); 3387 struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
@@ -3359,6 +3403,23 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
3359 return 0; 3403 return 0;
3360} 3404}
3361 3405
3406/* prevent security commands from being issued via ioctl */
3407static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
3408 struct nvdimm *nvdimm, unsigned int cmd, void *buf)
3409{
3410 struct nd_cmd_pkg *call_pkg = buf;
3411 unsigned int func;
3412
3413 if (nvdimm && cmd == ND_CMD_CALL &&
3414 call_pkg->nd_family == NVDIMM_FAMILY_INTEL) {
3415 func = call_pkg->nd_command;
3416 if ((1 << func) & NVDIMM_INTEL_SECURITY_CMDMASK)
3417 return -EOPNOTSUPP;
3418 }
3419
3420 return __acpi_nfit_clear_to_send(nd_desc, nvdimm, cmd);
3421}
3422
3362int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, 3423int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
3363 enum nfit_ars_state req_type) 3424 enum nfit_ars_state req_type)
3364{ 3425{
@@ -3474,7 +3535,13 @@ static int acpi_nfit_add(struct acpi_device *adev)
3474 3535
3475 status = acpi_get_table(ACPI_SIG_NFIT, 0, &tbl); 3536 status = acpi_get_table(ACPI_SIG_NFIT, 0, &tbl);
3476 if (ACPI_FAILURE(status)) { 3537 if (ACPI_FAILURE(status)) {
3477 /* This is ok, we could have an nvdimm hotplugged later */ 3538 /* The NVDIMM root device allows OS to trigger enumeration of
3539 * NVDIMMs through NFIT at boot time and re-enumeration at
3540 * root level via the _FIT method during runtime.
3541 * This is ok to return 0 here, we could have an nvdimm
3542 * hotplugged later and evaluate _FIT method which returns
3543 * data in the format of a series of NFIT Structures.
3544 */
3478 dev_dbg(dev, "failed to find NFIT at startup\n"); 3545 dev_dbg(dev, "failed to find NFIT at startup\n");
3479 return 0; 3546 return 0;
3480 } 3547 }
diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
new file mode 100644
index 000000000000..850b2927b4e7
--- /dev/null
+++ b/drivers/acpi/nfit/intel.c
@@ -0,0 +1,388 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
3#include <linux/libnvdimm.h>
4#include <linux/ndctl.h>
5#include <linux/acpi.h>
6#include <asm/smp.h>
7#include "intel.h"
8#include "nfit.h"
9
10static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm,
11 enum nvdimm_passphrase_type ptype)
12{
13 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
14 struct {
15 struct nd_cmd_pkg pkg;
16 struct nd_intel_get_security_state cmd;
17 } nd_cmd = {
18 .pkg = {
19 .nd_command = NVDIMM_INTEL_GET_SECURITY_STATE,
20 .nd_family = NVDIMM_FAMILY_INTEL,
21 .nd_size_out =
22 sizeof(struct nd_intel_get_security_state),
23 .nd_fw_size =
24 sizeof(struct nd_intel_get_security_state),
25 },
26 };
27 int rc;
28
29 if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask))
30 return -ENXIO;
31
32 /*
33 * Short circuit the state retrieval while we are doing overwrite.
34 * The DSM spec states that the security state is indeterminate
35 * until the overwrite DSM completes.
36 */
37 if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER)
38 return NVDIMM_SECURITY_OVERWRITE;
39
40 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
41 if (rc < 0)
42 return rc;
43 if (nd_cmd.cmd.status)
44 return -EIO;
45
46 /* check and see if security is enabled and locked */
47 if (ptype == NVDIMM_MASTER) {
48 if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED)
49 return NVDIMM_SECURITY_UNLOCKED;
50 else if (nd_cmd.cmd.extended_state &
51 ND_INTEL_SEC_ESTATE_PLIMIT)
52 return NVDIMM_SECURITY_FROZEN;
53 } else {
54 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED)
55 return -ENXIO;
56 else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) {
57 if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED)
58 return NVDIMM_SECURITY_LOCKED;
59 else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN
60 || nd_cmd.cmd.state &
61 ND_INTEL_SEC_STATE_PLIMIT)
62 return NVDIMM_SECURITY_FROZEN;
63 else
64 return NVDIMM_SECURITY_UNLOCKED;
65 }
66 }
67
68 /* this should cover master security disabled as well */
69 return NVDIMM_SECURITY_DISABLED;
70}
71
72static int intel_security_freeze(struct nvdimm *nvdimm)
73{
74 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
75 struct {
76 struct nd_cmd_pkg pkg;
77 struct nd_intel_freeze_lock cmd;
78 } nd_cmd = {
79 .pkg = {
80 .nd_command = NVDIMM_INTEL_FREEZE_LOCK,
81 .nd_family = NVDIMM_FAMILY_INTEL,
82 .nd_size_out = ND_INTEL_STATUS_SIZE,
83 .nd_fw_size = ND_INTEL_STATUS_SIZE,
84 },
85 };
86 int rc;
87
88 if (!test_bit(NVDIMM_INTEL_FREEZE_LOCK, &nfit_mem->dsm_mask))
89 return -ENOTTY;
90
91 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
92 if (rc < 0)
93 return rc;
94 if (nd_cmd.cmd.status)
95 return -EIO;
96 return 0;
97}
98
99static int intel_security_change_key(struct nvdimm *nvdimm,
100 const struct nvdimm_key_data *old_data,
101 const struct nvdimm_key_data *new_data,
102 enum nvdimm_passphrase_type ptype)
103{
104 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
105 unsigned int cmd = ptype == NVDIMM_MASTER ?
106 NVDIMM_INTEL_SET_MASTER_PASSPHRASE :
107 NVDIMM_INTEL_SET_PASSPHRASE;
108 struct {
109 struct nd_cmd_pkg pkg;
110 struct nd_intel_set_passphrase cmd;
111 } nd_cmd = {
112 .pkg = {
113 .nd_family = NVDIMM_FAMILY_INTEL,
114 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE * 2,
115 .nd_size_out = ND_INTEL_STATUS_SIZE,
116 .nd_fw_size = ND_INTEL_STATUS_SIZE,
117 .nd_command = cmd,
118 },
119 };
120 int rc;
121
122 if (!test_bit(cmd, &nfit_mem->dsm_mask))
123 return -ENOTTY;
124
125 if (old_data)
126 memcpy(nd_cmd.cmd.old_pass, old_data->data,
127 sizeof(nd_cmd.cmd.old_pass));
128 memcpy(nd_cmd.cmd.new_pass, new_data->data,
129 sizeof(nd_cmd.cmd.new_pass));
130 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
131 if (rc < 0)
132 return rc;
133
134 switch (nd_cmd.cmd.status) {
135 case 0:
136 return 0;
137 case ND_INTEL_STATUS_INVALID_PASS:
138 return -EINVAL;
139 case ND_INTEL_STATUS_NOT_SUPPORTED:
140 return -EOPNOTSUPP;
141 case ND_INTEL_STATUS_INVALID_STATE:
142 default:
143 return -EIO;
144 }
145}
146
147static void nvdimm_invalidate_cache(void);
148
149static int intel_security_unlock(struct nvdimm *nvdimm,
150 const struct nvdimm_key_data *key_data)
151{
152 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
153 struct {
154 struct nd_cmd_pkg pkg;
155 struct nd_intel_unlock_unit cmd;
156 } nd_cmd = {
157 .pkg = {
158 .nd_command = NVDIMM_INTEL_UNLOCK_UNIT,
159 .nd_family = NVDIMM_FAMILY_INTEL,
160 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
161 .nd_size_out = ND_INTEL_STATUS_SIZE,
162 .nd_fw_size = ND_INTEL_STATUS_SIZE,
163 },
164 };
165 int rc;
166
167 if (!test_bit(NVDIMM_INTEL_UNLOCK_UNIT, &nfit_mem->dsm_mask))
168 return -ENOTTY;
169
170 memcpy(nd_cmd.cmd.passphrase, key_data->data,
171 sizeof(nd_cmd.cmd.passphrase));
172 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
173 if (rc < 0)
174 return rc;
175 switch (nd_cmd.cmd.status) {
176 case 0:
177 break;
178 case ND_INTEL_STATUS_INVALID_PASS:
179 return -EINVAL;
180 default:
181 return -EIO;
182 }
183
184 /* DIMM unlocked, invalidate all CPU caches before we read it */
185 nvdimm_invalidate_cache();
186
187 return 0;
188}
189
190static int intel_security_disable(struct nvdimm *nvdimm,
191 const struct nvdimm_key_data *key_data)
192{
193 int rc;
194 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
195 struct {
196 struct nd_cmd_pkg pkg;
197 struct nd_intel_disable_passphrase cmd;
198 } nd_cmd = {
199 .pkg = {
200 .nd_command = NVDIMM_INTEL_DISABLE_PASSPHRASE,
201 .nd_family = NVDIMM_FAMILY_INTEL,
202 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
203 .nd_size_out = ND_INTEL_STATUS_SIZE,
204 .nd_fw_size = ND_INTEL_STATUS_SIZE,
205 },
206 };
207
208 if (!test_bit(NVDIMM_INTEL_DISABLE_PASSPHRASE, &nfit_mem->dsm_mask))
209 return -ENOTTY;
210
211 memcpy(nd_cmd.cmd.passphrase, key_data->data,
212 sizeof(nd_cmd.cmd.passphrase));
213 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
214 if (rc < 0)
215 return rc;
216
217 switch (nd_cmd.cmd.status) {
218 case 0:
219 break;
220 case ND_INTEL_STATUS_INVALID_PASS:
221 return -EINVAL;
222 case ND_INTEL_STATUS_INVALID_STATE:
223 default:
224 return -ENXIO;
225 }
226
227 return 0;
228}
229
230static int intel_security_erase(struct nvdimm *nvdimm,
231 const struct nvdimm_key_data *key,
232 enum nvdimm_passphrase_type ptype)
233{
234 int rc;
235 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
236 unsigned int cmd = ptype == NVDIMM_MASTER ?
237 NVDIMM_INTEL_MASTER_SECURE_ERASE : NVDIMM_INTEL_SECURE_ERASE;
238 struct {
239 struct nd_cmd_pkg pkg;
240 struct nd_intel_secure_erase cmd;
241 } nd_cmd = {
242 .pkg = {
243 .nd_family = NVDIMM_FAMILY_INTEL,
244 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
245 .nd_size_out = ND_INTEL_STATUS_SIZE,
246 .nd_fw_size = ND_INTEL_STATUS_SIZE,
247 .nd_command = cmd,
248 },
249 };
250
251 if (!test_bit(cmd, &nfit_mem->dsm_mask))
252 return -ENOTTY;
253
254 /* flush all cache before we erase DIMM */
255 nvdimm_invalidate_cache();
256 memcpy(nd_cmd.cmd.passphrase, key->data,
257 sizeof(nd_cmd.cmd.passphrase));
258 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
259 if (rc < 0)
260 return rc;
261
262 switch (nd_cmd.cmd.status) {
263 case 0:
264 break;
265 case ND_INTEL_STATUS_NOT_SUPPORTED:
266 return -EOPNOTSUPP;
267 case ND_INTEL_STATUS_INVALID_PASS:
268 return -EINVAL;
269 case ND_INTEL_STATUS_INVALID_STATE:
270 default:
271 return -ENXIO;
272 }
273
274 /* DIMM erased, invalidate all CPU caches before we read it */
275 nvdimm_invalidate_cache();
276 return 0;
277}
278
279static int intel_security_query_overwrite(struct nvdimm *nvdimm)
280{
281 int rc;
282 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
283 struct {
284 struct nd_cmd_pkg pkg;
285 struct nd_intel_query_overwrite cmd;
286 } nd_cmd = {
287 .pkg = {
288 .nd_command = NVDIMM_INTEL_QUERY_OVERWRITE,
289 .nd_family = NVDIMM_FAMILY_INTEL,
290 .nd_size_out = ND_INTEL_STATUS_SIZE,
291 .nd_fw_size = ND_INTEL_STATUS_SIZE,
292 },
293 };
294
295 if (!test_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &nfit_mem->dsm_mask))
296 return -ENOTTY;
297
298 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
299 if (rc < 0)
300 return rc;
301
302 switch (nd_cmd.cmd.status) {
303 case 0:
304 break;
305 case ND_INTEL_STATUS_OQUERY_INPROGRESS:
306 return -EBUSY;
307 default:
308 return -ENXIO;
309 }
310
311 /* flush all cache before we make the nvdimms available */
312 nvdimm_invalidate_cache();
313 return 0;
314}
315
316static int intel_security_overwrite(struct nvdimm *nvdimm,
317 const struct nvdimm_key_data *nkey)
318{
319 int rc;
320 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
321 struct {
322 struct nd_cmd_pkg pkg;
323 struct nd_intel_overwrite cmd;
324 } nd_cmd = {
325 .pkg = {
326 .nd_command = NVDIMM_INTEL_OVERWRITE,
327 .nd_family = NVDIMM_FAMILY_INTEL,
328 .nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
329 .nd_size_out = ND_INTEL_STATUS_SIZE,
330 .nd_fw_size = ND_INTEL_STATUS_SIZE,
331 },
332 };
333
334 if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask))
335 return -ENOTTY;
336
337 /* flush all cache before we erase DIMM */
338 nvdimm_invalidate_cache();
339 if (nkey)
340 memcpy(nd_cmd.cmd.passphrase, nkey->data,
341 sizeof(nd_cmd.cmd.passphrase));
342 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
343 if (rc < 0)
344 return rc;
345
346 switch (nd_cmd.cmd.status) {
347 case 0:
348 return 0;
349 case ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED:
350 return -ENOTSUPP;
351 case ND_INTEL_STATUS_INVALID_PASS:
352 return -EINVAL;
353 case ND_INTEL_STATUS_INVALID_STATE:
354 default:
355 return -ENXIO;
356 }
357}
358
359/*
360 * TODO: define a cross arch wbinvd equivalent when/if
361 * NVDIMM_FAMILY_INTEL command support arrives on another arch.
362 */
363#ifdef CONFIG_X86
364static void nvdimm_invalidate_cache(void)
365{
366 wbinvd_on_all_cpus();
367}
368#else
369static void nvdimm_invalidate_cache(void)
370{
371 WARN_ON_ONCE("cache invalidation required after unlock\n");
372}
373#endif
374
375static const struct nvdimm_security_ops __intel_security_ops = {
376 .state = intel_security_state,
377 .freeze = intel_security_freeze,
378 .change_key = intel_security_change_key,
379 .disable = intel_security_disable,
380#ifdef CONFIG_X86
381 .unlock = intel_security_unlock,
382 .erase = intel_security_erase,
383 .overwrite = intel_security_overwrite,
384 .query_overwrite = intel_security_query_overwrite,
385#endif
386};
387
388const struct nvdimm_security_ops *intel_security_ops = &__intel_security_ops;
diff --git a/drivers/acpi/nfit/intel.h b/drivers/acpi/nfit/intel.h
index 86746312381f..0aca682ab9d7 100644
--- a/drivers/acpi/nfit/intel.h
+++ b/drivers/acpi/nfit/intel.h
@@ -35,4 +35,80 @@ struct nd_intel_smart {
35 }; 35 };
36} __packed; 36} __packed;
37 37
38extern const struct nvdimm_security_ops *intel_security_ops;
39
40#define ND_INTEL_STATUS_SIZE 4
41#define ND_INTEL_PASSPHRASE_SIZE 32
42
43#define ND_INTEL_STATUS_NOT_SUPPORTED 1
44#define ND_INTEL_STATUS_RETRY 5
45#define ND_INTEL_STATUS_NOT_READY 9
46#define ND_INTEL_STATUS_INVALID_STATE 10
47#define ND_INTEL_STATUS_INVALID_PASS 11
48#define ND_INTEL_STATUS_OVERWRITE_UNSUPPORTED 0x10007
49#define ND_INTEL_STATUS_OQUERY_INPROGRESS 0x10007
50#define ND_INTEL_STATUS_OQUERY_SEQUENCE_ERR 0x20007
51
52#define ND_INTEL_SEC_STATE_ENABLED 0x02
53#define ND_INTEL_SEC_STATE_LOCKED 0x04
54#define ND_INTEL_SEC_STATE_FROZEN 0x08
55#define ND_INTEL_SEC_STATE_PLIMIT 0x10
56#define ND_INTEL_SEC_STATE_UNSUPPORTED 0x20
57#define ND_INTEL_SEC_STATE_OVERWRITE 0x40
58
59#define ND_INTEL_SEC_ESTATE_ENABLED 0x01
60#define ND_INTEL_SEC_ESTATE_PLIMIT 0x02
61
62struct nd_intel_get_security_state {
63 u32 status;
64 u8 extended_state;
65 u8 reserved[3];
66 u8 state;
67 u8 reserved1[3];
68} __packed;
69
70struct nd_intel_set_passphrase {
71 u8 old_pass[ND_INTEL_PASSPHRASE_SIZE];
72 u8 new_pass[ND_INTEL_PASSPHRASE_SIZE];
73 u32 status;
74} __packed;
75
76struct nd_intel_unlock_unit {
77 u8 passphrase[ND_INTEL_PASSPHRASE_SIZE];
78 u32 status;
79} __packed;
80
81struct nd_intel_disable_passphrase {
82 u8 passphrase[ND_INTEL_PASSPHRASE_SIZE];
83 u32 status;
84} __packed;
85
86struct nd_intel_freeze_lock {
87 u32 status;
88} __packed;
89
90struct nd_intel_secure_erase {
91 u8 passphrase[ND_INTEL_PASSPHRASE_SIZE];
92 u32 status;
93} __packed;
94
95struct nd_intel_overwrite {
96 u8 passphrase[ND_INTEL_PASSPHRASE_SIZE];
97 u32 status;
98} __packed;
99
100struct nd_intel_query_overwrite {
101 u32 status;
102} __packed;
103
104struct nd_intel_set_master_passphrase {
105 u8 old_pass[ND_INTEL_PASSPHRASE_SIZE];
106 u8 new_pass[ND_INTEL_PASSPHRASE_SIZE];
107 u32 status;
108} __packed;
109
110struct nd_intel_master_secure_erase {
111 u8 passphrase[ND_INTEL_PASSPHRASE_SIZE];
112 u32 status;
113} __packed;
38#endif 114#endif
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index df0f6b8407e7..33691aecfcee 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -60,14 +60,33 @@ enum nvdimm_family_cmds {
60 NVDIMM_INTEL_QUERY_FWUPDATE = 16, 60 NVDIMM_INTEL_QUERY_FWUPDATE = 16,
61 NVDIMM_INTEL_SET_THRESHOLD = 17, 61 NVDIMM_INTEL_SET_THRESHOLD = 17,
62 NVDIMM_INTEL_INJECT_ERROR = 18, 62 NVDIMM_INTEL_INJECT_ERROR = 18,
63 NVDIMM_INTEL_GET_SECURITY_STATE = 19,
64 NVDIMM_INTEL_SET_PASSPHRASE = 20,
65 NVDIMM_INTEL_DISABLE_PASSPHRASE = 21,
66 NVDIMM_INTEL_UNLOCK_UNIT = 22,
67 NVDIMM_INTEL_FREEZE_LOCK = 23,
68 NVDIMM_INTEL_SECURE_ERASE = 24,
69 NVDIMM_INTEL_OVERWRITE = 25,
70 NVDIMM_INTEL_QUERY_OVERWRITE = 26,
71 NVDIMM_INTEL_SET_MASTER_PASSPHRASE = 27,
72 NVDIMM_INTEL_MASTER_SECURE_ERASE = 28,
63}; 73};
64 74
75#define NVDIMM_INTEL_SECURITY_CMDMASK \
76(1 << NVDIMM_INTEL_GET_SECURITY_STATE | 1 << NVDIMM_INTEL_SET_PASSPHRASE \
77| 1 << NVDIMM_INTEL_DISABLE_PASSPHRASE | 1 << NVDIMM_INTEL_UNLOCK_UNIT \
78| 1 << NVDIMM_INTEL_FREEZE_LOCK | 1 << NVDIMM_INTEL_SECURE_ERASE \
79| 1 << NVDIMM_INTEL_OVERWRITE | 1 << NVDIMM_INTEL_QUERY_OVERWRITE \
80| 1 << NVDIMM_INTEL_SET_MASTER_PASSPHRASE \
81| 1 << NVDIMM_INTEL_MASTER_SECURE_ERASE)
82
65#define NVDIMM_INTEL_CMDMASK \ 83#define NVDIMM_INTEL_CMDMASK \
66(NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \ 84(NVDIMM_STANDARD_CMDMASK | 1 << NVDIMM_INTEL_GET_MODES \
67 | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \ 85 | 1 << NVDIMM_INTEL_GET_FWINFO | 1 << NVDIMM_INTEL_START_FWUPDATE \
68 | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \ 86 | 1 << NVDIMM_INTEL_SEND_FWUPDATE | 1 << NVDIMM_INTEL_FINISH_FWUPDATE \
69 | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \ 87 | 1 << NVDIMM_INTEL_QUERY_FWUPDATE | 1 << NVDIMM_INTEL_SET_THRESHOLD \
70 | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN) 88 | 1 << NVDIMM_INTEL_INJECT_ERROR | 1 << NVDIMM_INTEL_LATCH_SHUTDOWN \
89 | NVDIMM_INTEL_SECURITY_CMDMASK)
71 90
72enum nfit_uuids { 91enum nfit_uuids {
73 /* for simplicity alias the uuid index with the family id */ 92 /* for simplicity alias the uuid index with the family id */
@@ -164,6 +183,8 @@ enum nfit_mem_flags {
164 NFIT_MEM_DIRTY_COUNT, 183 NFIT_MEM_DIRTY_COUNT,
165}; 184};
166 185
186#define NFIT_DIMM_ID_LEN 22
187
167/* assembled tables for a given dimm/memory-device */ 188/* assembled tables for a given dimm/memory-device */
168struct nfit_mem { 189struct nfit_mem {
169 struct nvdimm *nvdimm; 190 struct nvdimm *nvdimm;
@@ -181,6 +202,7 @@ struct nfit_mem {
181 struct list_head list; 202 struct list_head list;
182 struct acpi_device *adev; 203 struct acpi_device *adev;
183 struct acpi_nfit_desc *acpi_desc; 204 struct acpi_nfit_desc *acpi_desc;
205 char id[NFIT_DIMM_ID_LEN+1];
184 struct resource *flush_wpq; 206 struct resource *flush_wpq;
185 unsigned long dsm_mask; 207 unsigned long dsm_mask;
186 unsigned long flags; 208 unsigned long flags;
diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig
index 9d36473dc2a2..5e27918e4624 100644
--- a/drivers/nvdimm/Kconfig
+++ b/drivers/nvdimm/Kconfig
@@ -112,4 +112,9 @@ config OF_PMEM
112 112
113 Select Y if unsure. 113 Select Y if unsure.
114 114
115config NVDIMM_KEYS
116 def_bool y
117 depends on ENCRYPTED_KEYS
118 depends on (LIBNVDIMM=ENCRYPTED_KEYS) || LIBNVDIMM=m
119
115endif 120endif
diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile
index e8847045dac0..6f2a088afad6 100644
--- a/drivers/nvdimm/Makefile
+++ b/drivers/nvdimm/Makefile
@@ -27,3 +27,4 @@ libnvdimm-$(CONFIG_ND_CLAIM) += claim.o
27libnvdimm-$(CONFIG_BTT) += btt_devs.o 27libnvdimm-$(CONFIG_BTT) += btt_devs.o
28libnvdimm-$(CONFIG_NVDIMM_PFN) += pfn_devs.o 28libnvdimm-$(CONFIG_NVDIMM_PFN) += pfn_devs.o
29libnvdimm-$(CONFIG_NVDIMM_DAX) += dax_devs.o 29libnvdimm-$(CONFIG_NVDIMM_DAX) += dax_devs.o
30libnvdimm-$(CONFIG_NVDIMM_KEYS) += security.o
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index f1fb39921236..dca5f7a805cb 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -331,6 +331,12 @@ struct nvdimm_bus *to_nvdimm_bus(struct device *dev)
331} 331}
332EXPORT_SYMBOL_GPL(to_nvdimm_bus); 332EXPORT_SYMBOL_GPL(to_nvdimm_bus);
333 333
334struct nvdimm_bus *nvdimm_to_bus(struct nvdimm *nvdimm)
335{
336 return to_nvdimm_bus(nvdimm->dev.parent);
337}
338EXPORT_SYMBOL_GPL(nvdimm_to_bus);
339
334struct nvdimm_bus *nvdimm_bus_register(struct device *parent, 340struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
335 struct nvdimm_bus_descriptor *nd_desc) 341 struct nvdimm_bus_descriptor *nd_desc)
336{ 342{
@@ -344,12 +350,12 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
344 INIT_LIST_HEAD(&nvdimm_bus->mapping_list); 350 INIT_LIST_HEAD(&nvdimm_bus->mapping_list);
345 init_waitqueue_head(&nvdimm_bus->probe_wait); 351 init_waitqueue_head(&nvdimm_bus->probe_wait);
346 nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); 352 nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL);
347 mutex_init(&nvdimm_bus->reconfig_mutex);
348 badrange_init(&nvdimm_bus->badrange);
349 if (nvdimm_bus->id < 0) { 353 if (nvdimm_bus->id < 0) {
350 kfree(nvdimm_bus); 354 kfree(nvdimm_bus);
351 return NULL; 355 return NULL;
352 } 356 }
357 mutex_init(&nvdimm_bus->reconfig_mutex);
358 badrange_init(&nvdimm_bus->badrange);
353 nvdimm_bus->nd_desc = nd_desc; 359 nvdimm_bus->nd_desc = nd_desc;
354 nvdimm_bus->dev.parent = parent; 360 nvdimm_bus->dev.parent = parent;
355 nvdimm_bus->dev.release = nvdimm_bus_release; 361 nvdimm_bus->dev.release = nvdimm_bus_release;
@@ -387,9 +393,24 @@ static int child_unregister(struct device *dev, void *data)
387 * i.e. remove classless children 393 * i.e. remove classless children
388 */ 394 */
389 if (dev->class) 395 if (dev->class)
390 /* pass */; 396 return 0;
391 else 397
392 nd_device_unregister(dev, ND_SYNC); 398 if (is_nvdimm(dev)) {
399 struct nvdimm *nvdimm = to_nvdimm(dev);
400 bool dev_put = false;
401
402 /* We are shutting down. Make state frozen artificially. */
403 nvdimm_bus_lock(dev);
404 nvdimm->sec.state = NVDIMM_SECURITY_FROZEN;
405 if (test_and_clear_bit(NDD_WORK_PENDING, &nvdimm->flags))
406 dev_put = true;
407 nvdimm_bus_unlock(dev);
408 cancel_delayed_work_sync(&nvdimm->dwork);
409 if (dev_put)
410 put_device(dev);
411 }
412 nd_device_unregister(dev, ND_SYNC);
413
393 return 0; 414 return 0;
394} 415}
395 416
@@ -902,7 +923,7 @@ static int nd_cmd_clear_to_send(struct nvdimm_bus *nvdimm_bus,
902 923
903 /* ask the bus provider if it would like to block this request */ 924 /* ask the bus provider if it would like to block this request */
904 if (nd_desc->clear_to_send) { 925 if (nd_desc->clear_to_send) {
905 int rc = nd_desc->clear_to_send(nd_desc, nvdimm, cmd); 926 int rc = nd_desc->clear_to_send(nd_desc, nvdimm, cmd, data);
906 927
907 if (rc) 928 if (rc)
908 return rc; 929 return rc;
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c
index 9899c97138a3..0cf58cabc9ed 100644
--- a/drivers/nvdimm/dimm.c
+++ b/drivers/nvdimm/dimm.c
@@ -34,7 +34,11 @@ static int nvdimm_probe(struct device *dev)
34 return rc; 34 return rc;
35 } 35 }
36 36
37 /* reset locked, to be validated below... */ 37 /*
38 * The locked status bit reflects explicit status codes from the
39 * label reading commands, revalidate it each time the driver is
40 * activated and re-reads the label area.
41 */
38 nvdimm_clear_locked(dev); 42 nvdimm_clear_locked(dev);
39 43
40 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL); 44 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
@@ -52,6 +56,16 @@ static int nvdimm_probe(struct device *dev)
52 kref_init(&ndd->kref); 56 kref_init(&ndd->kref);
53 57
54 /* 58 /*
59 * Attempt to unlock, if the DIMM supports security commands,
60 * otherwise the locked indication is determined by explicit
61 * status codes from the label reading commands.
62 */
63 rc = nvdimm_security_unlock(dev);
64 if (rc < 0)
65 dev_dbg(dev, "failed to unlock dimm: %d\n", rc);
66
67
68 /*
55 * EACCES failures reading the namespace label-area-properties 69 * EACCES failures reading the namespace label-area-properties
56 * are interpreted as the DIMM capacity being locked but the 70 * are interpreted as the DIMM capacity being locked but the
57 * namespace labels themselves being accessible. 71 * namespace labels themselves being accessible.
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index 6c3de2317390..4890310df874 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -370,23 +370,172 @@ static ssize_t available_slots_show(struct device *dev,
370} 370}
371static DEVICE_ATTR_RO(available_slots); 371static DEVICE_ATTR_RO(available_slots);
372 372
373__weak ssize_t security_show(struct device *dev,
374 struct device_attribute *attr, char *buf)
375{
376 struct nvdimm *nvdimm = to_nvdimm(dev);
377
378 switch (nvdimm->sec.state) {
379 case NVDIMM_SECURITY_DISABLED:
380 return sprintf(buf, "disabled\n");
381 case NVDIMM_SECURITY_UNLOCKED:
382 return sprintf(buf, "unlocked\n");
383 case NVDIMM_SECURITY_LOCKED:
384 return sprintf(buf, "locked\n");
385 case NVDIMM_SECURITY_FROZEN:
386 return sprintf(buf, "frozen\n");
387 case NVDIMM_SECURITY_OVERWRITE:
388 return sprintf(buf, "overwrite\n");
389 default:
390 return -ENOTTY;
391 }
392
393 return -ENOTTY;
394}
395
396#define OPS \
397 C( OP_FREEZE, "freeze", 1), \
398 C( OP_DISABLE, "disable", 2), \
399 C( OP_UPDATE, "update", 3), \
400 C( OP_ERASE, "erase", 2), \
401 C( OP_OVERWRITE, "overwrite", 2), \
402 C( OP_MASTER_UPDATE, "master_update", 3), \
403 C( OP_MASTER_ERASE, "master_erase", 2)
404#undef C
405#define C(a, b, c) a
406enum nvdimmsec_op_ids { OPS };
407#undef C
408#define C(a, b, c) { b, c }
409static struct {
410 const char *name;
411 int args;
412} ops[] = { OPS };
413#undef C
414
415#define SEC_CMD_SIZE 32
416#define KEY_ID_SIZE 10
417
418static ssize_t __security_store(struct device *dev, const char *buf, size_t len)
419{
420 struct nvdimm *nvdimm = to_nvdimm(dev);
421 ssize_t rc;
422 char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1],
423 nkeystr[KEY_ID_SIZE+1];
424 unsigned int key, newkey;
425 int i;
426
427 if (atomic_read(&nvdimm->busy))
428 return -EBUSY;
429
430 rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s"
431 " %"__stringify(KEY_ID_SIZE)"s"
432 " %"__stringify(KEY_ID_SIZE)"s",
433 cmd, keystr, nkeystr);
434 if (rc < 1)
435 return -EINVAL;
436 for (i = 0; i < ARRAY_SIZE(ops); i++)
437 if (sysfs_streq(cmd, ops[i].name))
438 break;
439 if (i >= ARRAY_SIZE(ops))
440 return -EINVAL;
441 if (ops[i].args > 1)
442 rc = kstrtouint(keystr, 0, &key);
443 if (rc >= 0 && ops[i].args > 2)
444 rc = kstrtouint(nkeystr, 0, &newkey);
445 if (rc < 0)
446 return rc;
447
448 if (i == OP_FREEZE) {
449 dev_dbg(dev, "freeze\n");
450 rc = nvdimm_security_freeze(nvdimm);
451 } else if (i == OP_DISABLE) {
452 dev_dbg(dev, "disable %u\n", key);
453 rc = nvdimm_security_disable(nvdimm, key);
454 } else if (i == OP_UPDATE) {
455 dev_dbg(dev, "update %u %u\n", key, newkey);
456 rc = nvdimm_security_update(nvdimm, key, newkey, NVDIMM_USER);
457 } else if (i == OP_ERASE) {
458 dev_dbg(dev, "erase %u\n", key);
459 rc = nvdimm_security_erase(nvdimm, key, NVDIMM_USER);
460 } else if (i == OP_OVERWRITE) {
461 dev_dbg(dev, "overwrite %u\n", key);
462 rc = nvdimm_security_overwrite(nvdimm, key);
463 } else if (i == OP_MASTER_UPDATE) {
464 dev_dbg(dev, "master_update %u %u\n", key, newkey);
465 rc = nvdimm_security_update(nvdimm, key, newkey,
466 NVDIMM_MASTER);
467 } else if (i == OP_MASTER_ERASE) {
468 dev_dbg(dev, "master_erase %u\n", key);
469 rc = nvdimm_security_erase(nvdimm, key,
470 NVDIMM_MASTER);
471 } else
472 return -EINVAL;
473
474 if (rc == 0)
475 rc = len;
476 return rc;
477}
478
479static ssize_t security_store(struct device *dev,
480 struct device_attribute *attr, const char *buf, size_t len)
481
482{
483 ssize_t rc;
484
485 /*
486 * Require all userspace triggered security management to be
487 * done while probing is idle and the DIMM is not in active use
488 * in any region.
489 */
490 device_lock(dev);
491 nvdimm_bus_lock(dev);
492 wait_nvdimm_bus_probe_idle(dev);
493 rc = __security_store(dev, buf, len);
494 nvdimm_bus_unlock(dev);
495 device_unlock(dev);
496
497 return rc;
498}
499static DEVICE_ATTR_RW(security);
500
373static struct attribute *nvdimm_attributes[] = { 501static struct attribute *nvdimm_attributes[] = {
374 &dev_attr_state.attr, 502 &dev_attr_state.attr,
375 &dev_attr_flags.attr, 503 &dev_attr_flags.attr,
376 &dev_attr_commands.attr, 504 &dev_attr_commands.attr,
377 &dev_attr_available_slots.attr, 505 &dev_attr_available_slots.attr,
506 &dev_attr_security.attr,
378 NULL, 507 NULL,
379}; 508};
380 509
510static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n)
511{
512 struct device *dev = container_of(kobj, typeof(*dev), kobj);
513 struct nvdimm *nvdimm = to_nvdimm(dev);
514
515 if (a != &dev_attr_security.attr)
516 return a->mode;
517 if (nvdimm->sec.state < 0)
518 return 0;
519 /* Are there any state mutation ops? */
520 if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable
521 || nvdimm->sec.ops->change_key
522 || nvdimm->sec.ops->erase
523 || nvdimm->sec.ops->overwrite)
524 return a->mode;
525 return 0444;
526}
527
381struct attribute_group nvdimm_attribute_group = { 528struct attribute_group nvdimm_attribute_group = {
382 .attrs = nvdimm_attributes, 529 .attrs = nvdimm_attributes,
530 .is_visible = nvdimm_visible,
383}; 531};
384EXPORT_SYMBOL_GPL(nvdimm_attribute_group); 532EXPORT_SYMBOL_GPL(nvdimm_attribute_group);
385 533
386struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 534struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
387 const struct attribute_group **groups, unsigned long flags, 535 void *provider_data, const struct attribute_group **groups,
388 unsigned long cmd_mask, int num_flush, 536 unsigned long flags, unsigned long cmd_mask, int num_flush,
389 struct resource *flush_wpq) 537 struct resource *flush_wpq, const char *dimm_id,
538 const struct nvdimm_security_ops *sec_ops)
390{ 539{
391 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); 540 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL);
392 struct device *dev; 541 struct device *dev;
@@ -399,6 +548,8 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
399 kfree(nvdimm); 548 kfree(nvdimm);
400 return NULL; 549 return NULL;
401 } 550 }
551
552 nvdimm->dimm_id = dimm_id;
402 nvdimm->provider_data = provider_data; 553 nvdimm->provider_data = provider_data;
403 nvdimm->flags = flags; 554 nvdimm->flags = flags;
404 nvdimm->cmd_mask = cmd_mask; 555 nvdimm->cmd_mask = cmd_mask;
@@ -411,11 +562,60 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
411 dev->type = &nvdimm_device_type; 562 dev->type = &nvdimm_device_type;
412 dev->devt = MKDEV(nvdimm_major, nvdimm->id); 563 dev->devt = MKDEV(nvdimm_major, nvdimm->id);
413 dev->groups = groups; 564 dev->groups = groups;
565 nvdimm->sec.ops = sec_ops;
566 nvdimm->sec.overwrite_tmo = 0;
567 INIT_DELAYED_WORK(&nvdimm->dwork, nvdimm_security_overwrite_query);
568 /*
569 * Security state must be initialized before device_add() for
570 * attribute visibility.
571 */
572 /* get security state and extended (master) state */
573 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
574 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
414 nd_device_register(dev); 575 nd_device_register(dev);
415 576
416 return nvdimm; 577 return nvdimm;
417} 578}
418EXPORT_SYMBOL_GPL(nvdimm_create); 579EXPORT_SYMBOL_GPL(__nvdimm_create);
580
581int nvdimm_security_setup_events(struct nvdimm *nvdimm)
582{
583 nvdimm->sec.overwrite_state = sysfs_get_dirent(nvdimm->dev.kobj.sd,
584 "security");
585 if (!nvdimm->sec.overwrite_state)
586 return -ENODEV;
587 return 0;
588}
589EXPORT_SYMBOL_GPL(nvdimm_security_setup_events);
590
591int nvdimm_in_overwrite(struct nvdimm *nvdimm)
592{
593 return test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags);
594}
595EXPORT_SYMBOL_GPL(nvdimm_in_overwrite);
596
597int nvdimm_security_freeze(struct nvdimm *nvdimm)
598{
599 int rc;
600
601 WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm->dev));
602
603 if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze)
604 return -EOPNOTSUPP;
605
606 if (nvdimm->sec.state < 0)
607 return -EIO;
608
609 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
610 dev_warn(&nvdimm->dev, "Overwrite operation in progress.\n");
611 return -EBUSY;
612 }
613
614 rc = nvdimm->sec.ops->freeze(nvdimm);
615 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
616
617 return rc;
618}
419 619
420int alias_dpa_busy(struct device *dev, void *data) 620int alias_dpa_busy(struct device *dev, void *data)
421{ 621{
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 750dbaa6ce82..a11bf4e6b451 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -944,8 +944,7 @@ static int __blk_label_update(struct nd_region *nd_region,
944 victims = 0; 944 victims = 0;
945 if (old_num_resources) { 945 if (old_num_resources) {
946 /* convert old local-label-map to dimm-slot victim-map */ 946 /* convert old local-label-map to dimm-slot victim-map */
947 victim_map = kcalloc(BITS_TO_LONGS(nslot), sizeof(long), 947 victim_map = bitmap_zalloc(nslot, GFP_KERNEL);
948 GFP_KERNEL);
949 if (!victim_map) 948 if (!victim_map)
950 return -ENOMEM; 949 return -ENOMEM;
951 950
@@ -968,7 +967,7 @@ static int __blk_label_update(struct nd_region *nd_region,
968 /* don't allow updates that consume the last label */ 967 /* don't allow updates that consume the last label */
969 if (nfree - alloc < 0 || nfree - alloc + victims < 1) { 968 if (nfree - alloc < 0 || nfree - alloc + victims < 1) {
970 dev_info(&nsblk->common.dev, "insufficient label space\n"); 969 dev_info(&nsblk->common.dev, "insufficient label space\n");
971 kfree(victim_map); 970 bitmap_free(victim_map);
972 return -ENOSPC; 971 return -ENOSPC;
973 } 972 }
974 /* from here on we need to abort on error */ 973 /* from here on we need to abort on error */
@@ -1140,7 +1139,7 @@ static int __blk_label_update(struct nd_region *nd_region,
1140 1139
1141 out: 1140 out:
1142 kfree(old_res_list); 1141 kfree(old_res_list);
1143 kfree(victim_map); 1142 bitmap_free(victim_map);
1144 return rc; 1143 return rc;
1145 1144
1146 abort: 1145 abort:
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 681af3a8fd62..4b077555ac70 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -270,11 +270,10 @@ static ssize_t __alt_name_store(struct device *dev, const char *buf,
270 if (dev->driver || to_ndns(dev)->claim) 270 if (dev->driver || to_ndns(dev)->claim)
271 return -EBUSY; 271 return -EBUSY;
272 272
273 input = kmemdup(buf, len + 1, GFP_KERNEL); 273 input = kstrndup(buf, len, GFP_KERNEL);
274 if (!input) 274 if (!input)
275 return -ENOMEM; 275 return -ENOMEM;
276 276
277 input[len] = '\0';
278 pos = strim(input); 277 pos = strim(input);
279 if (strlen(pos) + 1 > NSLABEL_NAME_LEN) { 278 if (strlen(pos) + 1 > NSLABEL_NAME_LEN) {
280 rc = -EINVAL; 279 rc = -EINVAL;
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index d0c621b32f72..2b2cf4e554d3 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -21,6 +21,7 @@
21extern struct list_head nvdimm_bus_list; 21extern struct list_head nvdimm_bus_list;
22extern struct mutex nvdimm_bus_list_mutex; 22extern struct mutex nvdimm_bus_list_mutex;
23extern int nvdimm_major; 23extern int nvdimm_major;
24extern struct workqueue_struct *nvdimm_wq;
24 25
25struct nvdimm_bus { 26struct nvdimm_bus {
26 struct nvdimm_bus_descriptor *nd_desc; 27 struct nvdimm_bus_descriptor *nd_desc;
@@ -41,8 +42,64 @@ struct nvdimm {
41 atomic_t busy; 42 atomic_t busy;
42 int id, num_flush; 43 int id, num_flush;
43 struct resource *flush_wpq; 44 struct resource *flush_wpq;
45 const char *dimm_id;
46 struct {
47 const struct nvdimm_security_ops *ops;
48 enum nvdimm_security_state state;
49 enum nvdimm_security_state ext_state;
50 unsigned int overwrite_tmo;
51 struct kernfs_node *overwrite_state;
52 } sec;
53 struct delayed_work dwork;
44}; 54};
45 55
56static inline enum nvdimm_security_state nvdimm_security_state(
57 struct nvdimm *nvdimm, bool master)
58{
59 if (!nvdimm->sec.ops)
60 return -ENXIO;
61
62 return nvdimm->sec.ops->state(nvdimm, master);
63}
64int nvdimm_security_freeze(struct nvdimm *nvdimm);
65#if IS_ENABLED(CONFIG_NVDIMM_KEYS)
66int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid);
67int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
68 unsigned int new_keyid,
69 enum nvdimm_passphrase_type pass_type);
70int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
71 enum nvdimm_passphrase_type pass_type);
72int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid);
73void nvdimm_security_overwrite_query(struct work_struct *work);
74#else
75static inline int nvdimm_security_disable(struct nvdimm *nvdimm,
76 unsigned int keyid)
77{
78 return -EOPNOTSUPP;
79}
80static inline int nvdimm_security_update(struct nvdimm *nvdimm,
81 unsigned int keyid,
82 unsigned int new_keyid,
83 enum nvdimm_passphrase_type pass_type)
84{
85 return -EOPNOTSUPP;
86}
87static inline int nvdimm_security_erase(struct nvdimm *nvdimm,
88 unsigned int keyid,
89 enum nvdimm_passphrase_type pass_type)
90{
91 return -EOPNOTSUPP;
92}
93static inline int nvdimm_security_overwrite(struct nvdimm *nvdimm,
94 unsigned int keyid)
95{
96 return -EOPNOTSUPP;
97}
98static inline void nvdimm_security_overwrite_query(struct work_struct *work)
99{
100}
101#endif
102
46/** 103/**
47 * struct blk_alloc_info - tracking info for BLK dpa scanning 104 * struct blk_alloc_info - tracking info for BLK dpa scanning
48 * @nd_mapping: blk region mapping boundaries 105 * @nd_mapping: blk region mapping boundaries
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index e79cc8e5c114..cfde992684e7 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -250,6 +250,14 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
250void nvdimm_set_aliasing(struct device *dev); 250void nvdimm_set_aliasing(struct device *dev);
251void nvdimm_set_locked(struct device *dev); 251void nvdimm_set_locked(struct device *dev);
252void nvdimm_clear_locked(struct device *dev); 252void nvdimm_clear_locked(struct device *dev);
253#if IS_ENABLED(CONFIG_NVDIMM_KEYS)
254int nvdimm_security_unlock(struct device *dev);
255#else
256static inline int nvdimm_security_unlock(struct device *dev)
257{
258 return 0;
259}
260#endif
253struct nd_btt *to_nd_btt(struct device *dev); 261struct nd_btt *to_nd_btt(struct device *dev);
254 262
255struct nd_gen_sb { 263struct nd_gen_sb {
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index e7377f1028ef..e2818f94f292 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -79,6 +79,11 @@ int nd_region_activate(struct nd_region *nd_region)
79 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 79 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
80 struct nvdimm *nvdimm = nd_mapping->nvdimm; 80 struct nvdimm *nvdimm = nd_mapping->nvdimm;
81 81
82 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
83 nvdimm_bus_unlock(&nd_region->dev);
84 return -EBUSY;
85 }
86
82 /* at least one null hint slot per-dimm for the "no-hint" case */ 87 /* at least one null hint slot per-dimm for the "no-hint" case */
83 flush_data_size += sizeof(void *); 88 flush_data_size += sizeof(void *);
84 num_flush = min_not_zero(num_flush, nvdimm->num_flush); 89 num_flush = min_not_zero(num_flush, nvdimm->num_flush);
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
new file mode 100644
index 000000000000..f8bb746a549f
--- /dev/null
+++ b/drivers/nvdimm/security.c
@@ -0,0 +1,454 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
3
4#include <linux/module.h>
5#include <linux/device.h>
6#include <linux/ndctl.h>
7#include <linux/slab.h>
8#include <linux/io.h>
9#include <linux/mm.h>
10#include <linux/cred.h>
11#include <linux/key.h>
12#include <linux/key-type.h>
13#include <keys/user-type.h>
14#include <keys/encrypted-type.h>
15#include "nd-core.h"
16#include "nd.h"
17
18#define NVDIMM_BASE_KEY 0
19#define NVDIMM_NEW_KEY 1
20
21static bool key_revalidate = true;
22module_param(key_revalidate, bool, 0444);
23MODULE_PARM_DESC(key_revalidate, "Require key validation at init.");
24
25static void *key_data(struct key *key)
26{
27 struct encrypted_key_payload *epayload = dereference_key_locked(key);
28
29 lockdep_assert_held_read(&key->sem);
30
31 return epayload->decrypted_data;
32}
33
34static void nvdimm_put_key(struct key *key)
35{
36 if (!key)
37 return;
38
39 up_read(&key->sem);
40 key_put(key);
41}
42
43/*
44 * Retrieve kernel key for DIMM and request from user space if
45 * necessary. Returns a key held for read and must be put by
46 * nvdimm_put_key() before the usage goes out of scope.
47 */
48static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
49{
50 struct key *key = NULL;
51 static const char NVDIMM_PREFIX[] = "nvdimm:";
52 char desc[NVDIMM_KEY_DESC_LEN + sizeof(NVDIMM_PREFIX)];
53 struct device *dev = &nvdimm->dev;
54
55 sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id);
56 key = request_key(&key_type_encrypted, desc, "");
57 if (IS_ERR(key)) {
58 if (PTR_ERR(key) == -ENOKEY)
59 dev_dbg(dev, "request_key() found no key\n");
60 else
61 dev_dbg(dev, "request_key() upcall failed\n");
62 key = NULL;
63 } else {
64 struct encrypted_key_payload *epayload;
65
66 down_read(&key->sem);
67 epayload = dereference_key_locked(key);
68 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
69 up_read(&key->sem);
70 key_put(key);
71 key = NULL;
72 }
73 }
74
75 return key;
76}
77
78static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
79 key_serial_t id, int subclass)
80{
81 key_ref_t keyref;
82 struct key *key;
83 struct encrypted_key_payload *epayload;
84 struct device *dev = &nvdimm->dev;
85
86 keyref = lookup_user_key(id, 0, 0);
87 if (IS_ERR(keyref))
88 return NULL;
89
90 key = key_ref_to_ptr(keyref);
91 if (key->type != &key_type_encrypted) {
92 key_put(key);
93 return NULL;
94 }
95
96 dev_dbg(dev, "%s: key found: %#x\n", __func__, key_serial(key));
97
98 down_read_nested(&key->sem, subclass);
99 epayload = dereference_key_locked(key);
100 if (epayload->decrypted_datalen != NVDIMM_PASSPHRASE_LEN) {
101 up_read(&key->sem);
102 key_put(key);
103 key = NULL;
104 }
105 return key;
106}
107
108static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm)
109{
110 struct key *key;
111 int rc;
112
113 if (!nvdimm->sec.ops->change_key)
114 return NULL;
115
116 key = nvdimm_request_key(nvdimm);
117 if (!key)
118 return NULL;
119
120 /*
121 * Send the same key to the hardware as new and old key to
122 * verify that the key is good.
123 */
124 rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key),
125 key_data(key), NVDIMM_USER);
126 if (rc < 0) {
127 nvdimm_put_key(key);
128 key = NULL;
129 }
130 return key;
131}
132
133static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
134{
135 struct device *dev = &nvdimm->dev;
136 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
137 struct key *key = NULL;
138 int rc;
139
140 /* The bus lock should be held at the top level of the call stack */
141 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
142
143 if (!nvdimm->sec.ops || !nvdimm->sec.ops->unlock
144 || nvdimm->sec.state < 0)
145 return -EIO;
146
147 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
148 dev_dbg(dev, "Security operation in progress.\n");
149 return -EBUSY;
150 }
151
152 /*
153 * If the pre-OS has unlocked the DIMM, attempt to send the key
154 * from request_key() to the hardware for verification. Failure
155 * to revalidate the key against the hardware results in a
156 * freeze of the security configuration. I.e. if the OS does not
157 * have the key, security is being managed pre-OS.
158 */
159 if (nvdimm->sec.state == NVDIMM_SECURITY_UNLOCKED) {
160 if (!key_revalidate)
161 return 0;
162
163 key = nvdimm_key_revalidate(nvdimm);
164 if (!key)
165 return nvdimm_security_freeze(nvdimm);
166 } else
167 key = nvdimm_request_key(nvdimm);
168
169 if (!key)
170 return -ENOKEY;
171
172 rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
173 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
174 rc == 0 ? "success" : "fail");
175
176 nvdimm_put_key(key);
177 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
178 return rc;
179}
180
181int nvdimm_security_unlock(struct device *dev)
182{
183 struct nvdimm *nvdimm = to_nvdimm(dev);
184 int rc;
185
186 nvdimm_bus_lock(dev);
187 rc = __nvdimm_security_unlock(nvdimm);
188 nvdimm_bus_unlock(dev);
189 return rc;
190}
191
192int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
193{
194 struct device *dev = &nvdimm->dev;
195 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
196 struct key *key;
197 int rc;
198
199 /* The bus lock should be held at the top level of the call stack */
200 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
201
202 if (!nvdimm->sec.ops || !nvdimm->sec.ops->disable
203 || nvdimm->sec.state < 0)
204 return -EOPNOTSUPP;
205
206 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
207 dev_dbg(dev, "Incorrect security state: %d\n",
208 nvdimm->sec.state);
209 return -EIO;
210 }
211
212 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
213 dev_dbg(dev, "Security operation in progress.\n");
214 return -EBUSY;
215 }
216
217 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
218 if (!key)
219 return -ENOKEY;
220
221 rc = nvdimm->sec.ops->disable(nvdimm, key_data(key));
222 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key),
223 rc == 0 ? "success" : "fail");
224
225 nvdimm_put_key(key);
226 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
227 return rc;
228}
229
230int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
231 unsigned int new_keyid,
232 enum nvdimm_passphrase_type pass_type)
233{
234 struct device *dev = &nvdimm->dev;
235 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
236 struct key *key, *newkey;
237 int rc;
238
239 /* The bus lock should be held at the top level of the call stack */
240 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
241
242 if (!nvdimm->sec.ops || !nvdimm->sec.ops->change_key
243 || nvdimm->sec.state < 0)
244 return -EOPNOTSUPP;
245
246 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
247 dev_dbg(dev, "Incorrect security state: %d\n",
248 nvdimm->sec.state);
249 return -EIO;
250 }
251
252 if (keyid == 0)
253 key = NULL;
254 else {
255 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
256 if (!key)
257 return -ENOKEY;
258 }
259
260 newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY);
261 if (!newkey) {
262 nvdimm_put_key(key);
263 return -ENOKEY;
264 }
265
266 rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL,
267 key_data(newkey), pass_type);
268 dev_dbg(dev, "key: %d %d update%s: %s\n",
269 key_serial(key), key_serial(newkey),
270 pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
271 rc == 0 ? "success" : "fail");
272
273 nvdimm_put_key(newkey);
274 nvdimm_put_key(key);
275 if (pass_type == NVDIMM_MASTER)
276 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm,
277 NVDIMM_MASTER);
278 else
279 nvdimm->sec.state = nvdimm_security_state(nvdimm,
280 NVDIMM_USER);
281 return rc;
282}
283
284int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
285 enum nvdimm_passphrase_type pass_type)
286{
287 struct device *dev = &nvdimm->dev;
288 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
289 struct key *key;
290 int rc;
291
292 /* The bus lock should be held at the top level of the call stack */
293 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
294
295 if (!nvdimm->sec.ops || !nvdimm->sec.ops->erase
296 || nvdimm->sec.state < 0)
297 return -EOPNOTSUPP;
298
299 if (atomic_read(&nvdimm->busy)) {
300 dev_dbg(dev, "Unable to secure erase while DIMM active.\n");
301 return -EBUSY;
302 }
303
304 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
305 dev_dbg(dev, "Incorrect security state: %d\n",
306 nvdimm->sec.state);
307 return -EIO;
308 }
309
310 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
311 dev_dbg(dev, "Security operation in progress.\n");
312 return -EBUSY;
313 }
314
315 if (nvdimm->sec.ext_state != NVDIMM_SECURITY_UNLOCKED
316 && pass_type == NVDIMM_MASTER) {
317 dev_dbg(dev,
318 "Attempt to secure erase in wrong master state.\n");
319 return -EOPNOTSUPP;
320 }
321
322 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
323 if (!key)
324 return -ENOKEY;
325
326 rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type);
327 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
328 pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
329 rc == 0 ? "success" : "fail");
330
331 nvdimm_put_key(key);
332 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
333 return rc;
334}
335
336int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
337{
338 struct device *dev = &nvdimm->dev;
339 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
340 struct key *key;
341 int rc;
342
343 /* The bus lock should be held at the top level of the call stack */
344 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
345
346 if (!nvdimm->sec.ops || !nvdimm->sec.ops->overwrite
347 || nvdimm->sec.state < 0)
348 return -EOPNOTSUPP;
349
350 if (atomic_read(&nvdimm->busy)) {
351 dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
352 return -EBUSY;
353 }
354
355 if (dev->driver == NULL) {
356 dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
357 return -EINVAL;
358 }
359
360 if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
361 dev_dbg(dev, "Incorrect security state: %d\n",
362 nvdimm->sec.state);
363 return -EIO;
364 }
365
366 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
367 dev_dbg(dev, "Security operation in progress.\n");
368 return -EBUSY;
369 }
370
371 if (keyid == 0)
372 key = NULL;
373 else {
374 key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
375 if (!key)
376 return -ENOKEY;
377 }
378
379 rc = nvdimm->sec.ops->overwrite(nvdimm, key ? key_data(key) : NULL);
380 dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key),
381 rc == 0 ? "success" : "fail");
382
383 nvdimm_put_key(key);
384 if (rc == 0) {
385 set_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags);
386 set_bit(NDD_WORK_PENDING, &nvdimm->flags);
387 nvdimm->sec.state = NVDIMM_SECURITY_OVERWRITE;
388 /*
389 * Make sure we don't lose device while doing overwrite
390 * query.
391 */
392 get_device(dev);
393 queue_delayed_work(system_wq, &nvdimm->dwork, 0);
394 }
395
396 return rc;
397}
398
399void __nvdimm_security_overwrite_query(struct nvdimm *nvdimm)
400{
401 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nvdimm->dev);
402 int rc;
403 unsigned int tmo;
404
405 /* The bus lock should be held at the top level of the call stack */
406 lockdep_assert_held(&nvdimm_bus->reconfig_mutex);
407
408 /*
409 * Abort and release device if we no longer have the overwrite
410 * flag set. It means the work has been canceled.
411 */
412 if (!test_bit(NDD_WORK_PENDING, &nvdimm->flags))
413 return;
414
415 tmo = nvdimm->sec.overwrite_tmo;
416
417 if (!nvdimm->sec.ops || !nvdimm->sec.ops->query_overwrite
418 || nvdimm->sec.state < 0)
419 return;
420
421 rc = nvdimm->sec.ops->query_overwrite(nvdimm);
422 if (rc == -EBUSY) {
423
424 /* setup delayed work again */
425 tmo += 10;
426 queue_delayed_work(system_wq, &nvdimm->dwork, tmo * HZ);
427 nvdimm->sec.overwrite_tmo = min(15U * 60U, tmo);
428 return;
429 }
430
431 if (rc < 0)
432 dev_dbg(&nvdimm->dev, "overwrite failed\n");
433 else
434 dev_dbg(&nvdimm->dev, "overwrite completed\n");
435
436 if (nvdimm->sec.overwrite_state)
437 sysfs_notify_dirent(nvdimm->sec.overwrite_state);
438 nvdimm->sec.overwrite_tmo = 0;
439 clear_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags);
440 clear_bit(NDD_WORK_PENDING, &nvdimm->flags);
441 put_device(&nvdimm->dev);
442 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
443 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
444}
445
446void nvdimm_security_overwrite_query(struct work_struct *work)
447{
448 struct nvdimm *nvdimm =
449 container_of(work, typeof(*nvdimm), dwork.work);
450
451 nvdimm_bus_lock(&nvdimm->dev);
452 __nvdimm_security_overwrite_query(nvdimm);
453 nvdimm_bus_unlock(&nvdimm->dev);
454}