summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2018-12-10 10:53:22 -0700
committerDan Williams <dan.j.williams@intel.com>2018-12-21 12:44:41 -0800
commit89fa9d8ea7bdfa841d19044485cec5f4171069e5 (patch)
tree2be60d02c3f6baac9186566e9077a7879a523fac /drivers/acpi
parent7d988097c546187ada602cc9bccd0f03d473eb8f (diff)
acpi/nfit, libnvdimm/security: add Intel DSM 1.8 master passphrase support
With Intel DSM 1.8 [1] two new security DSMs are introduced. Enable/update master passphrase and master secure erase. The master passphrase allows a secure erase to be performed without the user passphrase that is set on the NVDIMM. The commands of master_update and master_erase are added to the sysfs knob in order to initiate the DSMs. They are similar in opeartion mechanism compare to update and erase. [1]: http://pmem.io/documents/NVDIMM_DSM_Interface-V1.8.pdf Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/nfit/core.c2
-rw-r--r--drivers/acpi/nfit/intel.c53
2 files changed, 38 insertions, 17 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index ab57a3fe4511..c246e71c5345 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -389,6 +389,8 @@ static u8 nfit_dsm_revid(unsigned family, unsigned func)
[NVDIMM_INTEL_SECURE_ERASE] = 2,
[NVDIMM_INTEL_OVERWRITE] = 2,
[NVDIMM_INTEL_QUERY_OVERWRITE] = 2,
+ [NVDIMM_INTEL_SET_MASTER_PASSPHRASE] = 2,
+ [NVDIMM_INTEL_MASTER_SECURE_ERASE] = 2,
},
};
u8 id;
diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
index 82e805d4458a..850b2927b4e7 100644
--- a/drivers/acpi/nfit/intel.c
+++ b/drivers/acpi/nfit/intel.c
@@ -7,7 +7,8 @@
#include "intel.h"
#include "nfit.h"
-static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm)
+static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm,
+ enum nvdimm_passphrase_type ptype)
{
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
struct {
@@ -33,7 +34,7 @@ static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm)
* The DSM spec states that the security state is indeterminate
* until the overwrite DSM completes.
*/
- if (nvdimm_in_overwrite(nvdimm))
+ if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER)
return NVDIMM_SECURITY_OVERWRITE;
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -43,17 +44,28 @@ static enum nvdimm_security_state intel_security_state(struct nvdimm *nvdimm)
return -EIO;
/* check and see if security is enabled and locked */
- if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED)
- return -ENXIO;
- else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) {
- if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED)
- return NVDIMM_SECURITY_LOCKED;
- else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN ||
- nd_cmd.cmd.state & ND_INTEL_SEC_STATE_PLIMIT)
- return NVDIMM_SECURITY_FROZEN;
- else
+ if (ptype == NVDIMM_MASTER) {
+ if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED)
return NVDIMM_SECURITY_UNLOCKED;
+ else if (nd_cmd.cmd.extended_state &
+ ND_INTEL_SEC_ESTATE_PLIMIT)
+ return NVDIMM_SECURITY_FROZEN;
+ } else {
+ if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED)
+ return -ENXIO;
+ else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) {
+ if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_LOCKED)
+ return NVDIMM_SECURITY_LOCKED;
+ else if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN
+ || nd_cmd.cmd.state &
+ ND_INTEL_SEC_STATE_PLIMIT)
+ return NVDIMM_SECURITY_FROZEN;
+ else
+ return NVDIMM_SECURITY_UNLOCKED;
+ }
}
+
+ /* this should cover master security disabled as well */
return NVDIMM_SECURITY_DISABLED;
}
@@ -86,24 +98,28 @@ static int intel_security_freeze(struct nvdimm *nvdimm)
static int intel_security_change_key(struct nvdimm *nvdimm,
const struct nvdimm_key_data *old_data,
- const struct nvdimm_key_data *new_data)
+ const struct nvdimm_key_data *new_data,
+ enum nvdimm_passphrase_type ptype)
{
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+ unsigned int cmd = ptype == NVDIMM_MASTER ?
+ NVDIMM_INTEL_SET_MASTER_PASSPHRASE :
+ NVDIMM_INTEL_SET_PASSPHRASE;
struct {
struct nd_cmd_pkg pkg;
struct nd_intel_set_passphrase cmd;
} nd_cmd = {
.pkg = {
- .nd_command = NVDIMM_INTEL_SET_PASSPHRASE,
.nd_family = NVDIMM_FAMILY_INTEL,
.nd_size_in = ND_INTEL_PASSPHRASE_SIZE * 2,
.nd_size_out = ND_INTEL_STATUS_SIZE,
.nd_fw_size = ND_INTEL_STATUS_SIZE,
+ .nd_command = cmd,
},
};
int rc;
- if (!test_bit(NVDIMM_INTEL_SET_PASSPHRASE, &nfit_mem->dsm_mask))
+ if (!test_bit(cmd, &nfit_mem->dsm_mask))
return -ENOTTY;
if (old_data)
@@ -212,10 +228,13 @@ static int intel_security_disable(struct nvdimm *nvdimm,
}
static int intel_security_erase(struct nvdimm *nvdimm,
- const struct nvdimm_key_data *key)
+ const struct nvdimm_key_data *key,
+ enum nvdimm_passphrase_type ptype)
{
int rc;
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+ unsigned int cmd = ptype == NVDIMM_MASTER ?
+ NVDIMM_INTEL_MASTER_SECURE_ERASE : NVDIMM_INTEL_SECURE_ERASE;
struct {
struct nd_cmd_pkg pkg;
struct nd_intel_secure_erase cmd;
@@ -225,11 +244,11 @@ static int intel_security_erase(struct nvdimm *nvdimm,
.nd_size_in = ND_INTEL_PASSPHRASE_SIZE,
.nd_size_out = ND_INTEL_STATUS_SIZE,
.nd_fw_size = ND_INTEL_STATUS_SIZE,
- .nd_command = NVDIMM_INTEL_SECURE_ERASE,
+ .nd_command = cmd,
},
};
- if (!test_bit(NVDIMM_INTEL_SECURE_ERASE, &nfit_mem->dsm_mask))
+ if (!test_bit(cmd, &nfit_mem->dsm_mask))
return -ENOTTY;
/* flush all cache before we erase DIMM */