summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2019-08-26 20:55:05 -0400
committerDan Williams <dan.j.williams@intel.com>2019-08-29 16:51:57 -0400
commit7b60422cb796d40431337becf2129fd9944b2f05 (patch)
tree50cacd59a7d6691b0c2ff43a7705dcc46c2d98e5
parentbc4f2199ca3107809df96cf72f618b9559b00a21 (diff)
libnvdimm/security: Consolidate 'security' operations
The security operations are exported from libnvdimm/security.c to libnvdimm/dimm_devs.c, and libnvdimm/security.c is optionally compiled based on the CONFIG_NVDIMM_KEYS config symbol. Rather than export the operations across compile objects, just move the __security_store() entry point to live with the helpers. Acked-by: Jeff Moyer <jmoyer@redhat.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/156686730515.184120.10522747907309996674.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/dimm_devs.c84
-rw-r--r--drivers/nvdimm/nd-core.h30
-rw-r--r--drivers/nvdimm/security.c90
3 files changed, 90 insertions, 114 deletions
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index d837cb9be83d..196aa44c4936 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -393,88 +393,6 @@ static ssize_t frozen_show(struct device *dev,
393} 393}
394static DEVICE_ATTR_RO(frozen); 394static DEVICE_ATTR_RO(frozen);
395 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 rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s"
428 " %"__stringify(KEY_ID_SIZE)"s"
429 " %"__stringify(KEY_ID_SIZE)"s",
430 cmd, keystr, nkeystr);
431 if (rc < 1)
432 return -EINVAL;
433 for (i = 0; i < ARRAY_SIZE(ops); i++)
434 if (sysfs_streq(cmd, ops[i].name))
435 break;
436 if (i >= ARRAY_SIZE(ops))
437 return -EINVAL;
438 if (ops[i].args > 1)
439 rc = kstrtouint(keystr, 0, &key);
440 if (rc >= 0 && ops[i].args > 2)
441 rc = kstrtouint(nkeystr, 0, &newkey);
442 if (rc < 0)
443 return rc;
444
445 if (i == OP_FREEZE) {
446 dev_dbg(dev, "freeze\n");
447 rc = nvdimm_security_freeze(nvdimm);
448 } else if (i == OP_DISABLE) {
449 dev_dbg(dev, "disable %u\n", key);
450 rc = nvdimm_security_disable(nvdimm, key);
451 } else if (i == OP_UPDATE || i == OP_MASTER_UPDATE) {
452 dev_dbg(dev, "%s %u %u\n", ops[i].name, key, newkey);
453 rc = nvdimm_security_update(nvdimm, key, newkey, i == OP_UPDATE
454 ? NVDIMM_USER : NVDIMM_MASTER);
455 } else if (i == OP_ERASE || i == OP_MASTER_ERASE) {
456 dev_dbg(dev, "%s %u\n", ops[i].name, key);
457 if (atomic_read(&nvdimm->busy)) {
458 dev_dbg(dev, "Unable to secure erase while DIMM active.\n");
459 return -EBUSY;
460 }
461 rc = nvdimm_security_erase(nvdimm, key, i == OP_ERASE
462 ? NVDIMM_USER : NVDIMM_MASTER);
463 } else if (i == OP_OVERWRITE) {
464 dev_dbg(dev, "overwrite %u\n", key);
465 if (atomic_read(&nvdimm->busy)) {
466 dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
467 return -EBUSY;
468 }
469 rc = nvdimm_security_overwrite(nvdimm, key);
470 } else
471 return -EINVAL;
472
473 if (rc == 0)
474 rc = len;
475 return rc;
476}
477
478static ssize_t security_store(struct device *dev, 396static ssize_t security_store(struct device *dev,
479 struct device_attribute *attr, const char *buf, size_t len) 397 struct device_attribute *attr, const char *buf, size_t len)
480 398
@@ -489,7 +407,7 @@ static ssize_t security_store(struct device *dev,
489 nd_device_lock(dev); 407 nd_device_lock(dev);
490 nvdimm_bus_lock(dev); 408 nvdimm_bus_lock(dev);
491 wait_nvdimm_bus_probe_idle(dev); 409 wait_nvdimm_bus_probe_idle(dev);
492 rc = __security_store(dev, buf, len); 410 rc = nvdimm_security_store(dev, buf, len);
493 nvdimm_bus_unlock(dev); 411 nvdimm_bus_unlock(dev);
494 nd_device_unlock(dev); 412 nd_device_unlock(dev);
495 413
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index da2bbfd56d9f..454454ba1738 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -68,35 +68,11 @@ static inline unsigned long nvdimm_security_flags(
68} 68}
69int nvdimm_security_freeze(struct nvdimm *nvdimm); 69int nvdimm_security_freeze(struct nvdimm *nvdimm);
70#if IS_ENABLED(CONFIG_NVDIMM_KEYS) 70#if IS_ENABLED(CONFIG_NVDIMM_KEYS)
71int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid); 71ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len);
72int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
73 unsigned int new_keyid,
74 enum nvdimm_passphrase_type pass_type);
75int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
76 enum nvdimm_passphrase_type pass_type);
77int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid);
78void nvdimm_security_overwrite_query(struct work_struct *work); 72void nvdimm_security_overwrite_query(struct work_struct *work);
79#else 73#else
80static inline int nvdimm_security_disable(struct nvdimm *nvdimm, 74static inline ssize_t nvdimm_security_store(struct device *dev,
81 unsigned int keyid) 75 const char *buf, size_t len)
82{
83 return -EOPNOTSUPP;
84}
85static inline int nvdimm_security_update(struct nvdimm *nvdimm,
86 unsigned int keyid,
87 unsigned int new_keyid,
88 enum nvdimm_passphrase_type pass_type)
89{
90 return -EOPNOTSUPP;
91}
92static inline int nvdimm_security_erase(struct nvdimm *nvdimm,
93 unsigned int keyid,
94 enum nvdimm_passphrase_type pass_type)
95{
96 return -EOPNOTSUPP;
97}
98static inline int nvdimm_security_overwrite(struct nvdimm *nvdimm,
99 unsigned int keyid)
100{ 76{
101 return -EOPNOTSUPP; 77 return -EOPNOTSUPP;
102} 78}
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 2166e627383a..9e45b207ff01 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -235,7 +235,7 @@ static int check_security_state(struct nvdimm *nvdimm)
235 return 0; 235 return 0;
236} 236}
237 237
238int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) 238static int security_disable(struct nvdimm *nvdimm, unsigned int keyid)
239{ 239{
240 struct device *dev = &nvdimm->dev; 240 struct device *dev = &nvdimm->dev;
241 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 241 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
@@ -268,7 +268,7 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
268 return rc; 268 return rc;
269} 269}
270 270
271int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, 271static int security_update(struct nvdimm *nvdimm, unsigned int keyid,
272 unsigned int new_keyid, 272 unsigned int new_keyid,
273 enum nvdimm_passphrase_type pass_type) 273 enum nvdimm_passphrase_type pass_type)
274{ 274{
@@ -318,7 +318,7 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
318 return rc; 318 return rc;
319} 319}
320 320
321int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, 321static int security_erase(struct nvdimm *nvdimm, unsigned int keyid,
322 enum nvdimm_passphrase_type pass_type) 322 enum nvdimm_passphrase_type pass_type)
323{ 323{
324 struct device *dev = &nvdimm->dev; 324 struct device *dev = &nvdimm->dev;
@@ -360,7 +360,7 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
360 return rc; 360 return rc;
361} 361}
362 362
363int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) 363static int security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
364{ 364{
365 struct device *dev = &nvdimm->dev; 365 struct device *dev = &nvdimm->dev;
366 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 366 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
@@ -465,3 +465,85 @@ void nvdimm_security_overwrite_query(struct work_struct *work)
465 __nvdimm_security_overwrite_query(nvdimm); 465 __nvdimm_security_overwrite_query(nvdimm);
466 nvdimm_bus_unlock(&nvdimm->dev); 466 nvdimm_bus_unlock(&nvdimm->dev);
467} 467}
468
469#define OPS \
470 C( OP_FREEZE, "freeze", 1), \
471 C( OP_DISABLE, "disable", 2), \
472 C( OP_UPDATE, "update", 3), \
473 C( OP_ERASE, "erase", 2), \
474 C( OP_OVERWRITE, "overwrite", 2), \
475 C( OP_MASTER_UPDATE, "master_update", 3), \
476 C( OP_MASTER_ERASE, "master_erase", 2)
477#undef C
478#define C(a, b, c) a
479enum nvdimmsec_op_ids { OPS };
480#undef C
481#define C(a, b, c) { b, c }
482static struct {
483 const char *name;
484 int args;
485} ops[] = { OPS };
486#undef C
487
488#define SEC_CMD_SIZE 32
489#define KEY_ID_SIZE 10
490
491ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len)
492{
493 struct nvdimm *nvdimm = to_nvdimm(dev);
494 ssize_t rc;
495 char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1],
496 nkeystr[KEY_ID_SIZE+1];
497 unsigned int key, newkey;
498 int i;
499
500 rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s"
501 " %"__stringify(KEY_ID_SIZE)"s"
502 " %"__stringify(KEY_ID_SIZE)"s",
503 cmd, keystr, nkeystr);
504 if (rc < 1)
505 return -EINVAL;
506 for (i = 0; i < ARRAY_SIZE(ops); i++)
507 if (sysfs_streq(cmd, ops[i].name))
508 break;
509 if (i >= ARRAY_SIZE(ops))
510 return -EINVAL;
511 if (ops[i].args > 1)
512 rc = kstrtouint(keystr, 0, &key);
513 if (rc >= 0 && ops[i].args > 2)
514 rc = kstrtouint(nkeystr, 0, &newkey);
515 if (rc < 0)
516 return rc;
517
518 if (i == OP_FREEZE) {
519 dev_dbg(dev, "freeze\n");
520 rc = nvdimm_security_freeze(nvdimm);
521 } else if (i == OP_DISABLE) {
522 dev_dbg(dev, "disable %u\n", key);
523 rc = security_disable(nvdimm, key);
524 } else if (i == OP_UPDATE || i == OP_MASTER_UPDATE) {
525 dev_dbg(dev, "%s %u %u\n", ops[i].name, key, newkey);
526 rc = security_update(nvdimm, key, newkey, i == OP_UPDATE
527 ? NVDIMM_USER : NVDIMM_MASTER);
528 } else if (i == OP_ERASE || i == OP_MASTER_ERASE) {
529 dev_dbg(dev, "%s %u\n", ops[i].name, key);
530 if (atomic_read(&nvdimm->busy)) {
531 dev_dbg(dev, "Unable to secure erase while DIMM active.\n");
532 return -EBUSY;
533 }
534 rc = security_erase(nvdimm, key, i == OP_ERASE
535 ? NVDIMM_USER : NVDIMM_MASTER);
536 } else if (i == OP_OVERWRITE) {
537 dev_dbg(dev, "overwrite %u\n", key);
538 if (atomic_read(&nvdimm->busy)) {
539 dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
540 return -EBUSY;
541 }
542 rc = security_overwrite(nvdimm, key);
543 } else
544 return -EINVAL;
545
546 if (rc == 0)
547 rc = len;
548 return rc;
549}