Adding test support for new Intel DSM from v1.8. The ability of simulating
master passphrase update and master secure erase have been added to
nfit_test.

Signed-off-by: Dave Jiang <dave.ji...@intel.com>
---
 tools/testing/nvdimm/test/nfit.c |   86 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index c885fe136f42..602f6703614e 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -148,7 +148,9 @@ static unsigned long dimm_fail_cmd_flags[NUM_DCR];
 static int dimm_fail_cmd_code[NUM_DCR];
 struct nfit_test_sec {
        u8 state;
+       u8 ext_state;
        u8 passphrase[32];
+       u8 master_passphrase[32];
        u64 overwrite_end_time;
 } dimm_sec_info[NUM_DCR];
 
@@ -951,6 +953,7 @@ static int nd_intel_test_cmd_security_status(struct 
nfit_test *t,
 
        nd_cmd->status = 0;
        nd_cmd->state = sec->state;
+       nd_cmd->extended_state = sec->ext_state;
        dev_dbg(dev, "security state (%#x) returned\n", nd_cmd->state);
 
        return 0;
@@ -1067,7 +1070,9 @@ static int nd_intel_test_cmd_secure_erase(struct 
nfit_test *t,
                dev_dbg(dev, "secure erase: wrong passphrase\n");
        } else {
                memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
+               memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
                sec->state = 0;
+               sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED;
                dev_dbg(dev, "secure erase: done\n");
        }
 
@@ -1112,12 +1117,69 @@ static int nd_intel_test_cmd_query_overwrite(struct 
nfit_test *t,
        if (time_is_before_jiffies64(sec->overwrite_end_time)) {
                sec->overwrite_end_time = 0;
                sec->state = 0;
+               sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED;
                dev_dbg(dev, "overwrite is complete\n");
        } else
                nd_cmd->status = ND_INTEL_STATUS_OQUERY_INPROGRESS;
        return 0;
 }
 
+static int nd_intel_test_cmd_master_set_pass(struct nfit_test *t,
+               struct nd_intel_set_master_passphrase *nd_cmd,
+               unsigned int buf_len, int dimm)
+{
+       struct device *dev = &t->pdev.dev;
+       struct nfit_test_sec *sec = &dimm_sec_info[dimm];
+
+       if (!(sec->ext_state & ND_INTEL_SEC_ESTATE_ENABLED)) {
+               nd_cmd->status = ND_INTEL_STATUS_NOT_SUPPORTED;
+               dev_dbg(dev, "master set passphrase in wrong state\n");
+       } else if (sec->ext_state & ND_INTEL_SEC_ESTATE_PLIMIT) {
+               nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
+               dev_dbg(dev, "master set passphrase in wrong security state\n");
+       } else if (memcmp(nd_cmd->old_pass, sec->master_passphrase,
+                               ND_INTEL_PASSPHRASE_SIZE) != 0) {
+               nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
+               dev_dbg(dev, "master set passphrase wrong passphrase\n");
+       } else {
+               memcpy(sec->master_passphrase, nd_cmd->new_pass,
+                               ND_INTEL_PASSPHRASE_SIZE);
+               nd_cmd->status = 0;
+               dev_dbg(dev, "master passphrase updated\n");
+       }
+
+       return 0;
+}
+
+static int nd_intel_test_cmd_master_secure_erase(struct nfit_test *t,
+               struct nd_intel_master_secure_erase *nd_cmd,
+               unsigned int buf_len, int dimm)
+{
+       struct device *dev = &t->pdev.dev;
+       struct nfit_test_sec *sec = &dimm_sec_info[dimm];
+
+       if (!(sec->ext_state & ND_INTEL_SEC_ESTATE_ENABLED)) {
+               nd_cmd->status = ND_INTEL_STATUS_NOT_SUPPORTED;
+               dev_dbg(dev, "master erase in wrong state\n");
+       } else if (sec->ext_state & ND_INTEL_SEC_ESTATE_PLIMIT) {
+               nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
+               dev_dbg(dev, "master erase in wrong security state\n");
+       } else if (memcmp(nd_cmd->passphrase, sec->master_passphrase,
+                               ND_INTEL_PASSPHRASE_SIZE) != 0) {
+               nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS;
+               dev_dbg(dev, "master secure erase: wrong passphrase\n");
+       } else {
+               memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
+               sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED;
+               memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
+               sec->state = 0;
+               dev_dbg(dev, "master secure erase: done\n");
+       }
+
+       return 0;
+}
+
+
 static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
 {
        int i;
@@ -1197,6 +1259,14 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor 
*nd_desc,
                                rc = nd_intel_test_cmd_query_overwrite(t,
                                                buf, buf_len, i - t->dcr_idx);
                                break;
+                       case NVDIMM_INTEL_SET_MASTER_PASSPHRASE:
+                               rc = nd_intel_test_cmd_master_set_pass(t,
+                                               buf, buf_len, i);
+                               break;
+                       case NVDIMM_INTEL_MASTER_SECURE_ERASE:
+                               rc = nd_intel_test_cmd_master_secure_erase(t,
+                                               buf, buf_len, i);
+                               break;
                        case ND_INTEL_ENABLE_LSS_STATUS:
                                rc = nd_intel_test_cmd_set_lss_status(t,
                                                buf, buf_len);
@@ -1575,6 +1645,17 @@ static int nfit_test_dimm_init(struct nfit_test *t)
        return 0;
 }
 
+static void security_init(struct nfit_test *t)
+{
+       int i;
+
+       for (i = 0; i < t->num_dcr; i++) {
+               struct nfit_test_sec *sec = &dimm_sec_info[i];
+
+               sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED;
+       }
+}
+
 static void smart_init(struct nfit_test *t)
 {
        int i;
@@ -1653,6 +1734,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
        if (nfit_test_dimm_init(t))
                return -ENOMEM;
        smart_init(t);
+       security_init(t);
        return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
 
@@ -2434,6 +2516,10 @@ static void nfit_test0_setup(struct nfit_test *t)
        set_bit(NVDIMM_INTEL_SECURE_ERASE, &acpi_desc->dimm_cmd_force_en);
        set_bit(NVDIMM_INTEL_OVERWRITE, &acpi_desc->dimm_cmd_force_en);
        set_bit(NVDIMM_INTEL_QUERY_OVERWRITE, &acpi_desc->dimm_cmd_force_en);
+       set_bit(NVDIMM_INTEL_SET_MASTER_PASSPHRASE,
+                       &acpi_desc->dimm_cmd_force_en);
+       set_bit(NVDIMM_INTEL_MASTER_SECURE_ERASE,
+                       &acpi_desc->dimm_cmd_force_en);
 }
 
 static void nfit_test1_setup(struct nfit_test *t)

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to