Re: [PATCH 1/2] libnvdimm/security: 'security' attr never show 'overwrite' state

2020-08-03 Thread Dave Jiang



On 8/3/2020 2:10 PM, Jane Chu wrote:

Hi, Dave,

On 8/3/2020 1:41 PM, Dave Jiang wrote:

On 7/24/2020 9:09 AM, Jane Chu wrote:

Since
commit d78c620a2e82 ("libnvdimm/security: Introduce a 'frozen' attribute"),
when issue
  # ndctl sanitize-dimm nmem0 --overwrite
then immediately check the 'security' attribute,
  # cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0012:00/ndbus0/nmem0/security
  unlocked
Actually the attribute stays 'unlocked' through out the entire overwrite
operation, never changed.  That's because 'nvdimm->sec.flags' is a bitmap
that has both bits set indicating 'overwrite' and 'unlocked'.
But security_show() checks the mutually exclusive bits before it checks
the 'overwrite' bit at last. The order should be reversed.

The commit also has a typo: in one occasion, 'nvdimm->sec.ext_state'
assignment is replaced with 'nvdimm->sec.flags' assignment for
the NVDIMM_MASTER type.


May be best to split this fix to a different patch? Just thinking git bisect 
later on to track issues. Otherwise Reviewed-by: Dave Jiang 



Sure. I take it you meant to separate the typo fix from the change that tests 
the OVERWRITE bit first?


Yep!



Regards,
-jane

___
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-le...@lists.01.org


Re: [PATCH 2/2] libnvdimm/security: ensure sysfs poll thread woke up and fetch updated attr

2020-08-03 Thread Dave Jiang




On 7/24/2020 9:09 AM, Jane Chu wrote:

commit 7d988097c546 ("acpi/nfit, libnvdimm/security: Add security DSM overwrite 
support")
adds a sysfs_notify_dirent() to wake up userspace poll thread when the 
"overwrite"
operation has completed. But the notification is issued before the internal
dimm security state and flags have been updated, so the userspace poll thread
wakes up and fetches the not-yet-updated attr and falls back to sleep, forever.
But if user from another terminal issue "ndctl wait-overwrite nmemX" again,
the command returns instantly.

Cc: Dave Jiang 
Cc: Dan Williams 
Fixes: 7d988097c546 ("acpi/nfit, libnvdimm/security: Add security DSM overwrite 
support")
Signed-off-by: Jane Chu 


Reviewed-by: Dave Jiang 


---
  drivers/nvdimm/security.c | 11 ---
  1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 8f3971c..4b80150 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -450,14 +450,19 @@ void __nvdimm_security_overwrite_query(struct nvdimm 
*nvdimm)
else
dev_dbg(>dev, "overwrite completed\n");
  
-	if (nvdimm->sec.overwrite_state)

-   sysfs_notify_dirent(nvdimm->sec.overwrite_state);
+   /*
+* Mark the overwrite work done and update dimm security flags,
+* then send a sysfs event notification to wake up userspace
+* poll threads to picked up the changed state.
+*/
nvdimm->sec.overwrite_tmo = 0;
clear_bit(NDD_SECURITY_OVERWRITE, >flags);
clear_bit(NDD_WORK_PENDING, >flags);
-   put_device(>dev);
nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER);
+   if (nvdimm->sec.overwrite_state)
+   sysfs_notify_dirent(nvdimm->sec.overwrite_state);
+   put_device(>dev);
  }
  
  void nvdimm_security_overwrite_query(struct work_struct *work)



___
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-le...@lists.01.org


Re: [PATCH 1/2] libnvdimm/security: 'security' attr never show 'overwrite' state

2020-08-03 Thread Dave Jiang




On 7/24/2020 9:09 AM, Jane Chu wrote:

Since
commit d78c620a2e82 ("libnvdimm/security: Introduce a 'frozen' attribute"),
when issue
  # ndctl sanitize-dimm nmem0 --overwrite
then immediately check the 'security' attribute,
  # cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0012:00/ndbus0/nmem0/security
  unlocked
Actually the attribute stays 'unlocked' through out the entire overwrite
operation, never changed.  That's because 'nvdimm->sec.flags' is a bitmap
that has both bits set indicating 'overwrite' and 'unlocked'.
But security_show() checks the mutually exclusive bits before it checks
the 'overwrite' bit at last. The order should be reversed.

The commit also has a typo: in one occasion, 'nvdimm->sec.ext_state'
assignment is replaced with 'nvdimm->sec.flags' assignment for
the NVDIMM_MASTER type.


May be best to split this fix to a different patch? Just thinking git bisect 
later on to track issues. Otherwise Reviewed-by: Dave Jiang 




Cc: Dan Williams 
Fixes: d78c620a2e82 ("libnvdimm/security: Introduce a 'frozen' attribute")
Signed-off-by: Jane Chu 
---
  drivers/nvdimm/dimm_devs.c | 4 ++--
  drivers/nvdimm/security.c  | 2 +-
  2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index b7b77e8..5d72026 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -363,14 +363,14 @@ __weak ssize_t security_show(struct device *dev,
  {
struct nvdimm *nvdimm = to_nvdimm(dev);
  
+	if (test_bit(NVDIMM_SECURITY_OVERWRITE, >sec.flags))

+   return sprintf(buf, "overwrite\n");
if (test_bit(NVDIMM_SECURITY_DISABLED, >sec.flags))
return sprintf(buf, "disabled\n");
if (test_bit(NVDIMM_SECURITY_UNLOCKED, >sec.flags))
return sprintf(buf, "unlocked\n");
if (test_bit(NVDIMM_SECURITY_LOCKED, >sec.flags))
return sprintf(buf, "locked\n");
-   if (test_bit(NVDIMM_SECURITY_OVERWRITE, >sec.flags))
-   return sprintf(buf, "overwrite\n");
return -ENOTTY;
  }
  
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c

index 4cef69b..8f3971c 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -457,7 +457,7 @@ void __nvdimm_security_overwrite_query(struct nvdimm 
*nvdimm)
clear_bit(NDD_WORK_PENDING, >flags);
put_device(>dev);
nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
-   nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER);
+   nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER);
  }
  
  void nvdimm_security_overwrite_query(struct work_struct *work)



___
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-le...@lists.01.org


Re: [PATCH] libnvdimm/security: Fix key lookup permissions

2020-07-07 Thread Dave Jiang




On 6/23/2020 9:35 PM, Dan Williams wrote:

As of commit 8c0637e950d6 ("keys: Make the KEY_NEED_* perms an enum rather
than a mask") lookup_user_key() needs an explicit declaration of what it
wants to do with the key. Add KEY_NEED_SEARCH to fix a warning with the
below signature, and fixes the inability to retrieve a key.

 WARNING: CPU: 15 PID: 6276 at security/keys/permission.c:35 
key_task_permission+0xd3/0x140
 [..]
 RIP: 0010:key_task_permission+0xd3/0x140
 [..]
 Call Trace:
  lookup_user_key+0xeb/0x6b0
  ? vsscanf+0x3df/0x840
  ? key_validate+0x50/0x50
  ? key_default_cmp+0x20/0x20
  nvdimm_get_user_key_payload.part.0+0x21/0x110 [libnvdimm]
  nvdimm_security_store+0x67d/0xb20 [libnvdimm]
  security_store+0x67/0x1a0 [libnvdimm]
  kernfs_fop_write+0xcf/0x1c0
  vfs_write+0xde/0x1d0
  ksys_write+0x68/0xe0
  do_syscall_64+0x5c/0xa0
  entry_SYSCALL_64_after_hwframe+0x49/0xb3

Cc: Dan Williams 
Cc: Vishal Verma 
Cc: Dave Jiang 
Cc: Ira Weiny 
Suggested-by: David Howells 
Fixes: 8c0637e950d6 ("keys: Make the KEY_NEED_* perms an enum rather than a 
mask")
Signed-off-by: Dan Williams 


Reviewed-by: Dave Jiang 


---
  drivers/nvdimm/security.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 89b85970912d..4cef69bd3c1b 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -95,7 +95,7 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm 
*nvdimm,
struct encrypted_key_payload *epayload;
struct device *dev = >dev;
  
-	keyref = lookup_user_key(id, 0, 0);

+   keyref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
if (IS_ERR(keyref))
return NULL;
  


___
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-le...@lists.01.org


[PATCH v2] libnvdimm: prevent nvdimm from requesting key when security is disabled

2019-09-24 Thread Dave Jiang
Current implementation attempts to request keys from the keyring even when
security is not enabled. Change behavior so when security is disabled it
will skip key request.

Error messages seen when no keys are installed and libnvdimm is loaded:

request-key[4598]: Cannot find command to construct key 661489677
request-key[4606]: Cannot find command to construct key 34713726
...

Fixes: 4c6926a23b76 ("acpi/nfit, libnvdimm: Add unlock of nvdimm support for 
Intel DIMMs")

Cc: sta...@vger.kernel.org
Signed-off-by: Dave Jiang 
---

v2:
- Fix up commit header to add more information and cc stable. (Dan)

 drivers/nvdimm/security.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 9e45b207ff01..89b85970912d 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -177,6 +177,10 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
|| !nvdimm->sec.flags)
return -EIO;
 
+   /* No need to go further if security is disabled */
+   if (test_bit(NVDIMM_SECURITY_DISABLED, >sec.flags))
+   return 0;
+
if (test_bit(NDD_SECURITY_OVERWRITE, >flags)) {
dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;

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


Re: [ndctl PATCH] libndctl: Fix a potentially non NUL-terminated string operation

2019-09-20 Thread Dave Jiang



On 9/20/19 11:06 AM, Vishal Verma wrote:
> Static analysis warns that pread() doesn't NUL-terminate buffers, and
> that we shouldn't pass it directly to strcmp. The sysfs string should
> normally have the right termination, but for correctness in the library,
> we shouldn't rely on that. Replace the strcmp() calls in question with
> an explicit strncmp().
> 
> Fixes: 3c0c7db045ec ("ndctl: add a wait-overwrite command")
> Cc: Dave Jiang 
> Cc: Dan Williams 
> Signed-off-by: Vishal Verma 

Reviewed-by: Dave Jiang 

> ---
>  ndctl/lib/dimm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
> index 2f145be..17344f0 100644
> --- a/ndctl/lib/dimm.c
> +++ b/ndctl/lib/dimm.c
> @@ -825,7 +825,7 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
> ndctl_dimm *dimm)
>   break;
>   }
>  
> - if (strcmp(buf, "overwrite") == 0) {
> + if (strncmp(buf, "overwrite", 9) == 0) {
>   rc = poll(, 1, -1);
>   if (rc < 0) {
>   rc = -errno;
> @@ -839,7 +839,7 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
> ndctl_dimm *dimm)
>   }
>   fds.revents = 0;
>   } else {
> - if (strcmp(buf, "disabled") == 0)
> + if (strncmp(buf, "disabled", 8) == 0)
>   rc = 1;
>   break;
>   }
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH] libnvdimm: prevent nvdimm from requesting key when security is disabled

2019-09-19 Thread Dave Jiang
Current implementation attempts to request keys from the keyring even when
security is not enabled. Change behavior so when security is disabled it
will skip key request.

Signed-off-by: Dave Jiang 
---
 drivers/nvdimm/security.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 9e45b207ff01..89b85970912d 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -177,6 +177,10 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
|| !nvdimm->sec.flags)
return -EIO;
 
+   /* No need to go further if security is disabled */
+   if (test_bit(NVDIMM_SECURITY_DISABLED, >sec.flags))
+   return 0;
+
if (test_bit(NDD_SECURITY_OVERWRITE, >flags)) {
dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;

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


Re: [PATCH v2 3/3] libnvdimm, MAINTAINERS: Maintainer Entry Profile

2019-09-11 Thread Dave Jiang



On 9/11/19 8:48 AM, Dan Williams wrote:
> Document the basic policies of the libnvdimm subsystem and provide a first
> example of a Maintainer Entry Profile for others to duplicate and edit.
> 
> Cc: Vishal Verma 
> Cc: Dave Jiang 
> Signed-off-by: Dan Williams 

Acked-by: Dave Jiang 

> ---
>  Documentation/nvdimm/maintainer-entry-profile.rst |   64 
> +
>  MAINTAINERS   |4 +
>  2 files changed, 68 insertions(+)
>  create mode 100644 Documentation/nvdimm/maintainer-entry-profile.rst
> 
> diff --git a/Documentation/nvdimm/maintainer-entry-profile.rst 
> b/Documentation/nvdimm/maintainer-entry-profile.rst
> new file mode 100644
> index ..c102950f2257
> --- /dev/null
> +++ b/Documentation/nvdimm/maintainer-entry-profile.rst
> @@ -0,0 +1,64 @@
> +LIBNVDIMM Maintainer Entry Profile
> +==
> +
> +Overview
> +
> +The libnvdimm subsystem manages persistent memory across multiple
> +architectures. The mailing list, is tracked by patchwork here:
> +https://patchwork.kernel.org/project/linux-nvdimm/list/
> +...and that instance is configured to give feedback to submitters on
> +patch acceptance and upstream merge. Patches are merged to either the
> +'libnvdimm-fixes', or 'libnvdimm-for-next' branch. Those branches are
> +available here:
> +https://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git/
> +
> +In general patches can be submitted against the latest -rc, however if
> +the incoming code change is dependent on other pending changes then the
> +patch should be based on the libnvdimm-for-next branch. However, since
> +persistent memory sits at the intersection of storage and memory there
> +are cases where patches are more suitable to be merged through a
> +Filesystem or the Memory Management tree. When in doubt copy the nvdimm
> +list and the maintainers will help route.
> +
> +Submissions will be exposed to the kbuild robot for compile regression
> +testing. It helps to get a success notification from that infrastructure
> +before submitting, but it is not required.
> +
> +
> +Submit Checklist Addendum
> +-
> +There are unit tests for the subsystem via the ndctl utility:
> +https://github.com/pmem/ndctl
> +Those tests need to be passed before the patches go upstream, but not
> +necessarily before initial posting. Contact the list if you need help
> +getting the test environment set up.
> +
> +
> +Key Cycle Dates
> +---
> +New submissions can be sent at any time, but if they intend to hit the
> +next merge window they should be sent before -rc4, and ideally
> +stabilized in the libnvdimm-for-next branch by -rc6. Of course if a
> +patch set requires more than 2 weeks of review -rc4 is already too late
> +and some patches may require multiple development cycles to review.
> +
> +
> +Coding Style Addendum
> +-
> +libnvdimm expects multi-line statements to be double indented. I.e.
> +
> +if (x...
> +&& ...y) {
> +
> +
> +Review Cadence
> +--
> +In general, please wait up to one week before pinging for feedback. A
> +private mail reminder is preferred. Alternatively ask for other
> +developers that have Reviewed-by tags for libnvdimm changes to take a
> +look and offer their opinion.
> +
> +
> +Style Cleanup Patches
> +-----
> +Standalone style-cleanups are welcome.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e5d111a86e61..2be1e18a368e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9185,6 +9185,7 @@ M:  Dan Williams 
>  M:   Vishal Verma 
>  M:   Dave Jiang 
>  L:   linux-nvdimm@lists.01.org
> +P:   Documentation/nvdimm/maintainer-entry-profile.rst
>  Q:   https://patchwork.kernel.org/project/linux-nvdimm/list/
>  S:   Supported
>  F:   drivers/nvdimm/blk.c
> @@ -9195,6 +9196,7 @@ M:  Vishal Verma 
>  M:   Dan Williams 
>  M:   Dave Jiang 
>  L:   linux-nvdimm@lists.01.org
> +P:   Documentation/nvdimm/maintainer-entry-profile.rst
>  Q:   https://patchwork.kernel.org/project/linux-nvdimm/list/
>  S:   Supported
>  F:   drivers/nvdimm/btt*
> @@ -9204,6 +9206,7 @@ M:  Dan Williams 
>  M:   Vishal Verma 
>  M:   Dave Jiang 
>  L:   linux-nvdimm@lists.01.org
> +P:   Documentation/nvdimm/maintainer-entry-profile.rst
>  Q:   https://patchwork.kernel.org/project/linux-nvdimm/list/
>  S:   Supported
>  F:   drivers/nvdimm/pmem*
> @@ -9223,6 +9226,7 @@ M:  Dave Jiang 
>  M:   Keith Busch 
>  M:   Ira Weiny 
>  L:   linux-nvdimm@lists.01.org
> +P:   Documentation/nvdimm/maintainer-entry-profile.rst
>  Q:   https://patchwork.kernel.org/project/linux-nvdimm/list/
>  T:   git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
>  S:   Supported
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH 0/3] libnvdimm/security: Enumerate the frozen state and other cleanups

2019-08-23 Thread Dave Jiang



On 8/14/19 6:20 PM, Dan Williams wrote:
> Jeff reported a scenario where ndctl was failing to unlock DIMMs [1].
> Through the course of debug it was discovered that the security
> interface on the DIMMs was in the 'frozen' state disallowing unlock, or
> any security operation.  Unfortunately the kernel only showed that the
> DIMMs were 'locked', not 'locked' and 'frozen'.
> 
> Introduce a new sysfs 'frozen' attribute so that ndctl can reflect the
> "security-operations-allowed" state independently of the lock status.
> Then, followup with cleanups related to replacing a security-state-enum
> with a set of flags.
> 
> [1]: https://lists.01.org/pipermail/linux-nvdimm/2019-August/022856.html
> ---
> 
> Dan Williams (3):
>   libnvdimm/security: Introduce a 'frozen' attribute
>   libnvdimm/security: Tighten scope of nvdimm->busy vs security operations
>   libnvdimm/security: Consolidate 'security' operations
> 
> 
>  drivers/acpi/nfit/intel.c|   65 +++-
>  drivers/nvdimm/bus.c |2 
>  drivers/nvdimm/dimm_devs.c   |  134 ++
>  drivers/nvdimm/nd-core.h |   51 --
>  drivers/nvdimm/security.c|  199 
> +-
>  include/linux/libnvdimm.h|9 +-
>  tools/testing/nvdimm/dimm_devs.c |   19 +---
>  7 files changed, 231 insertions(+), 248 deletions(-)
> 

For the series
Reviewed-by: Dave Jiang 
Thanks.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v2 3/3] ndctl: add unit test for load-keys

2019-03-28 Thread Dave Jiang
Add to security.sh to test load-keys for user keys.

Signed-off-by: Dave Jiang 
---

V2:
- Add quotes around $masterkey. (Vishal)
- Change fail to failed in output. (Vishal)

 test/security.sh |   68 --
 1 file changed, 61 insertions(+), 7 deletions(-)

diff --git a/test/security.sh b/test/security.sh
index 1b7a9a1a..8a36265f 100755
--- a/test/security.sh
+++ b/test/security.sh
@@ -6,8 +6,10 @@ rc=77
 dev=""
 id=""
 keypath="/etc/ndctl/keys"
-masterkey="nvdimm-master-test"
-masterpath="$keypath/$masterkey"
+masterkey="nvdimm-master"
+masterpath="$keypath/$masterkey.blob"
+backup_key=0
+backup_handle=0
 
 . ./common
 
@@ -32,6 +34,15 @@ setup_keys()
mkdir -p "$keypath"
fi
 
+   if [ -f "$masterpath" ]; then
+   mv "$masterpath" "$masterpath.bak"
+   $backup_key=1
+   fi
+   if [ -f "$keypath/tpm.handle" ]; then
+   mv "$keypath/tpm.handle" "$keypath/tmp.handle.bak"
+   $backup_handle=1
+   fi
+
dd if=/dev/urandom bs=1 count=32 2>/dev/null | keyctl padd user 
"$masterkey" @u
keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
 }
@@ -43,16 +54,25 @@ test_cleanup()
fi
 
if keyctl search @u user "$masterkey"; then
-   keyctl unlink "$(keyctl search @u user $masterkey)"
+   keyctl unlink "$(keyctl search @u user "$masterkey")"
fi
 
if [ -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob ]; then
rm -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob
fi
+}
 
+post_cleanup()
+{
if [ -f $masterpath ]; then
rm -f "$masterpath"
fi
+   if [ "$backup_key" -eq 1 ]; then
+   mv "$masterpath.bak" "$masterpath"
+   fi
+   if [ "$backup_handle" -eq 1 ]; then
+   mv "$keypath/tpm.handle.bak" "$keypath/tmp.handle"
+   fi
 }
 
 lock_dimm()
@@ -168,8 +188,8 @@ test_4_security_unlock()
remove_passphrase
 }
 
-# this should always be the last test. with security frozen, nfit_test must
-# be removed and is no longer usable
+# This should always be the last nvdimm security test.
+# with security frozen, nfit_test must be removed and is no longer usable
 test_5_security_freeze()
 {
setup_passphrase
@@ -188,6 +208,33 @@ test_5_security_freeze()
fi
 }
 
+test_6_load_keys()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user "$masterkey")"
+   fi
+
+   $NDCTL load-keys
+
+   if keyctl search @u user "$masterkey"; then
+   echo "master key loaded"
+   else
+   echo "master key failed to loaded"
+   err "$LINENO"
+   fi
+
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   echo "dimm key loaded"
+   else
+   echo "dimm key failed to load"
+   err "$LINENO"
+   fi
+}
+
 check_min_kver "5.0" || do_skip "may lack security handling"
 uid="$(keyctl show | grep -Eo "_uid.[0-9]+" | head -1 | cut -d. -f2-)"
 if [ "$uid" -ne 0 ]; then
@@ -210,11 +257,18 @@ test_3_security_setup_and_erase
 echo "Test 4, unlock dimm"
 test_4_security_unlock
 
-# Freeze should always be run last because it locks security state and require
-# nfit_test module unload.
+# Freeze should always be the last nvdimm security test because it locks
+# security state and require nfit_test module unload. However, this does
+# not impact any key management testing via libkeyctl.
 echo "Test 5, freeze security"
 test_5_security_freeze
 
+# Load-keys is independent of actual nvdimm security and is part of key
+# mangement testing.
+echo "Test 6, test load-keys"
+test_6_load_keys
+
 test_cleanup
+post_cleanup
 _cleanup
 exit 0

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


[PATCH v2 2/3] ndctl: fix key blob loading for user keys

2019-03-28 Thread Dave Jiang
The syntax for loading user master key is different than loading a trusted
key. Fix so we can load user key properly.

Signed-off-by: Dave Jiang 
---

v2: No change

 ndctl/load-keys.c |   13 +
 ndctl/util/keys.c |   20 +++-
 ndctl/util/keys.h |   10 --
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
index 7d86a94b..981f80f1 100644
--- a/ndctl/load-keys.c
+++ b/ndctl/load-keys.c
@@ -25,12 +25,7 @@ static struct parameters {
const char *tpm_handle;
 } param;
 
-enum key_type {
-   KEY_USER = 0,
-   KEY_TRUSTED,
-};
-
-static const char *key_names[] = {"user", "trusted"};
+static const char *key_names[] = {"user", "trusted", "encrypted"};
 
 static struct loadkeys {
enum key_type key_type;
@@ -44,6 +39,7 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
char *keypath)
char *blob;
int size, rc;
char path[PATH_MAX];
+   enum key_type;
 
rc = sprintf(path, "%s/nvdimm-master.blob", keypath);
if (rc < 0)
@@ -65,7 +61,8 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
char *keypath)
return -errno;
}
 
-   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1);
+   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1,
+   lk_ctx->key_type);
if (!blob)
return -ENOMEM;
 
@@ -122,7 +119,7 @@ static int load_dimm_keys(struct loadkeys *lk_ctx)
}
 
blob = ndctl_load_key_blob(dent->d_name, , NULL,
-   lk_ctx->dirfd);
+   lk_ctx->dirfd, KEY_ENCRYPTED);
if (!blob) {
free(fname);
continue;
diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index 622533d7..a621a5f5 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -103,13 +103,17 @@ static int get_key_desc(struct ndctl_dimm *dimm, char 
*desc,
 }
 
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd)
+   int dirfd, enum key_type key_type)
 {
struct stat st;
ssize_t read_bytes = 0;
int rc, fd;
char *blob, *pl, *rdptr;
char prefix[] = "load ";
+   bool need_prefix = false;
+
+   if (key_type == KEY_ENCRYPTED || key_type == KEY_TRUSTED)
+   need_prefix = true;
 
fd = openat(dirfd, path, O_RDONLY);
if (fd < 0) {
@@ -133,7 +137,10 @@ char *ndctl_load_key_blob(const char *path, int *size, 
const char *postfix,
return NULL;
}
 
-   *size = st.st_size + sizeof(prefix) - 1;
+   *size = st.st_size;
+   if (need_prefix)
+   *size += strlen(prefix);
+
/*
 * We need to increment postfix and space.
 * "keyhandle=" is 10 bytes, plus null termination.
@@ -146,8 +153,11 @@ char *ndctl_load_key_blob(const char *path, int *size, 
const char *postfix,
return NULL;
}
 
-   memcpy(blob, prefix, sizeof(prefix) - 1);
-   pl = blob + sizeof(prefix) - 1;
+   if (need_prefix) {
+   memcpy(blob, prefix, strlen(prefix));
+   pl = blob + strlen(prefix);
+   } else
+   pl = blob;
 
rdptr = pl;
do {
@@ -300,7 +310,7 @@ static key_serial_t dimm_load_key(struct ndctl_dimm *dimm,
if (rc < 0)
return rc;
 
-   blob = ndctl_load_key_blob(path, , NULL, -1);
+   blob = ndctl_load_key_blob(path, , NULL, -1, KEY_ENCRYPTED);
if (!blob)
return -ENOMEM;
 
diff --git a/ndctl/util/keys.h b/ndctl/util/keys.h
index eab78d2f..9bc995ac 100644
--- a/ndctl/util/keys.h
+++ b/ndctl/util/keys.h
@@ -12,9 +12,15 @@ enum ndctl_key_type {
ND_ZERO_KEY,
 };
 
+enum key_type {
+   KEY_USER = 0,
+   KEY_TRUSTED,
+   KEY_ENCRYPTED,
+};
+
 #ifdef ENABLE_KEYUTILS
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd);
+   int dirfd, enum key_type key_type);
 int ndctl_dimm_setup_key(struct ndctl_dimm *dimm, const char *kek,
enum ndctl_key_type key_type);
 int ndctl_dimm_update_key(struct ndctl_dimm *dimm, const char *kek,
@@ -25,7 +31,7 @@ int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
 int ndctl_dimm_overwrite_key(struct ndctl_dimm *dimm);
 #else
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd)
+   int dirfd, enum key_type key_type)
 {
return NULL;
 }

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


[PATCH v2 1/3] ndctl: fix load-keys for user master-key

2019-03-28 Thread Dave Jiang
load-keys incorrectly assumes that all keys have TPM handles. TPM handle is
only for trusted-keys. Fix in order to allow user master-key to operate.

Signed-off-by: Dave Jiang 
---

v2:
- Make output go to stderr. (Dan)


 ndctl/load-keys.c |6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
index 8e4998f2..7d86a94b 100644
--- a/ndctl/load-keys.c
+++ b/ndctl/load-keys.c
@@ -213,10 +213,8 @@ static int load_keys(struct loadkeys *lk_ctx, const char 
*keypath,
 
if (!tpmhandle) {
rc = check_tpm_handle(lk_ctx);
-   if (rc < 0) {
-   rc = -errno;
-   goto erropen;
-   }
+   if (rc < 0)
+   fprintf(stderr, "No TPM handle discovered.\n");
}
 
rc = load_master_key(lk_ctx, param.key_path);

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


Re: [PATCH 2/3] ndctl: fix key blob loading for user keys

2019-03-28 Thread Dave Jiang



On 3/28/19 12:18 PM, Dan Williams wrote:
> On Thu, Mar 28, 2019 at 12:07 PM Dave Jiang  wrote:
>>
>> The syntax for loading user master key is different than loading a trusted
>> key. Fix so we can load user key properly.
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>  ndctl/load-keys.c |   13 +
>>  ndctl/util/keys.c |   20 +++-
>>  ndctl/util/keys.h |   10 --
>>  3 files changed, 28 insertions(+), 15 deletions(-)
>>
>> diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
>> index 19380152..c0d0d743 100644
>> --- a/ndctl/load-keys.c
>> +++ b/ndctl/load-keys.c
>> @@ -25,12 +25,7 @@ static struct parameters {
>> const char *tpm_handle;
>>  } param;
>>
>> -enum key_type {
>> -   KEY_USER = 0,
>> -   KEY_TRUSTED,
>> -};
>> -
>> -static const char *key_names[] = {"user", "trusted"};
>> +static const char *key_names[] = {"user", "trusted", "encrypted"};
>>
>>  static struct loadkeys {
>> enum key_type key_type;
>> @@ -44,6 +39,7 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
>> char *keypath)
>> char *blob;
>> int size, rc;
>> char path[PATH_MAX];
>> +   enum key_type;
>>
>> rc = sprintf(path, "%s/nvdimm-master.blob", keypath);
>> if (rc < 0)
>> @@ -65,7 +61,8 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
>> char *keypath)
>> return -errno;
>> }
>>
>> -   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1);
>> +   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1,
>> +   lk_ctx->key_type);
> 
> Where is  lk_ctx->key_type set? I don't think I see any assignments in
> this patch.
> 

In ndctl/load-keys.c:load_master_key() previously. It's not new.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH 1/3] ndctl: fix load-keys for user master-key

2019-03-28 Thread Dave Jiang



On 3/28/19 12:11 PM, Dan Williams wrote:
> On Thu, Mar 28, 2019 at 12:07 PM Dave Jiang  wrote:
>>
>> load-keys incorrectly assumes that all keys have TPM handles. TPM handle is
>> only for trusted-keys. Fix in order to allow user master-key work.
> 
> s/work/to operate/ ?
> 
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>  ndctl/load-keys.c |6 ++
>>  1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
>> index 8e4998f2..19380152 100644
>> --- a/ndctl/load-keys.c
>> +++ b/ndctl/load-keys.c
>> @@ -213,10 +213,8 @@ static int load_keys(struct loadkeys *lk_ctx, const 
>> char *keypath,
>>
>> if (!tpmhandle) {
>> rc = check_tpm_handle(lk_ctx);
>> -   if (rc < 0) {
>> -   rc = -errno;
>> -   goto erropen;
>> -   }
>> +   if (rc < 0)
>> +   printf("No TPM handle discovered.\n");
> 
> Please keep error messages on stderr.

Actually this is info. At this point we do not have context as to if a
trusted key or user key being loaded, and it could be we are using user
master key or it could be TPM handle can't be found.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH 1/3] ndctl: fix load-keys for user master-key

2019-03-28 Thread Dave Jiang
load-keys incorrectly assumes that all keys have TPM handles. TPM handle is
only for trusted-keys. Fix in order to allow user master-key work.

Signed-off-by: Dave Jiang 
---
 ndctl/load-keys.c |6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
index 8e4998f2..19380152 100644
--- a/ndctl/load-keys.c
+++ b/ndctl/load-keys.c
@@ -213,10 +213,8 @@ static int load_keys(struct loadkeys *lk_ctx, const char 
*keypath,
 
if (!tpmhandle) {
rc = check_tpm_handle(lk_ctx);
-   if (rc < 0) {
-   rc = -errno;
-   goto erropen;
-   }
+   if (rc < 0)
+   printf("No TPM handle discovered.\n");
}
 
rc = load_master_key(lk_ctx, param.key_path);

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


[PATCH 2/3] ndctl: fix key blob loading for user keys

2019-03-28 Thread Dave Jiang
The syntax for loading user master key is different than loading a trusted
key. Fix so we can load user key properly.

Signed-off-by: Dave Jiang 
---
 ndctl/load-keys.c |   13 +
 ndctl/util/keys.c |   20 +++-
 ndctl/util/keys.h |   10 --
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/ndctl/load-keys.c b/ndctl/load-keys.c
index 19380152..c0d0d743 100644
--- a/ndctl/load-keys.c
+++ b/ndctl/load-keys.c
@@ -25,12 +25,7 @@ static struct parameters {
const char *tpm_handle;
 } param;
 
-enum key_type {
-   KEY_USER = 0,
-   KEY_TRUSTED,
-};
-
-static const char *key_names[] = {"user", "trusted"};
+static const char *key_names[] = {"user", "trusted", "encrypted"};
 
 static struct loadkeys {
enum key_type key_type;
@@ -44,6 +39,7 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
char *keypath)
char *blob;
int size, rc;
char path[PATH_MAX];
+   enum key_type;
 
rc = sprintf(path, "%s/nvdimm-master.blob", keypath);
if (rc < 0)
@@ -65,7 +61,8 @@ static int load_master_key(struct loadkeys *lk_ctx, const 
char *keypath)
return -errno;
}
 
-   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1);
+   blob = ndctl_load_key_blob(path, , param.tpm_handle, -1,
+   lk_ctx->key_type);
if (!blob)
return -ENOMEM;
 
@@ -122,7 +119,7 @@ static int load_dimm_keys(struct loadkeys *lk_ctx)
}
 
blob = ndctl_load_key_blob(dent->d_name, , NULL,
-   lk_ctx->dirfd);
+   lk_ctx->dirfd, KEY_ENCRYPTED);
if (!blob) {
free(fname);
continue;
diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index 622533d7..a621a5f5 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -103,13 +103,17 @@ static int get_key_desc(struct ndctl_dimm *dimm, char 
*desc,
 }
 
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd)
+   int dirfd, enum key_type key_type)
 {
struct stat st;
ssize_t read_bytes = 0;
int rc, fd;
char *blob, *pl, *rdptr;
char prefix[] = "load ";
+   bool need_prefix = false;
+
+   if (key_type == KEY_ENCRYPTED || key_type == KEY_TRUSTED)
+   need_prefix = true;
 
fd = openat(dirfd, path, O_RDONLY);
if (fd < 0) {
@@ -133,7 +137,10 @@ char *ndctl_load_key_blob(const char *path, int *size, 
const char *postfix,
return NULL;
}
 
-   *size = st.st_size + sizeof(prefix) - 1;
+   *size = st.st_size;
+   if (need_prefix)
+   *size += strlen(prefix);
+
/*
 * We need to increment postfix and space.
 * "keyhandle=" is 10 bytes, plus null termination.
@@ -146,8 +153,11 @@ char *ndctl_load_key_blob(const char *path, int *size, 
const char *postfix,
return NULL;
}
 
-   memcpy(blob, prefix, sizeof(prefix) - 1);
-   pl = blob + sizeof(prefix) - 1;
+   if (need_prefix) {
+   memcpy(blob, prefix, strlen(prefix));
+   pl = blob + strlen(prefix);
+   } else
+   pl = blob;
 
rdptr = pl;
do {
@@ -300,7 +310,7 @@ static key_serial_t dimm_load_key(struct ndctl_dimm *dimm,
if (rc < 0)
return rc;
 
-   blob = ndctl_load_key_blob(path, , NULL, -1);
+   blob = ndctl_load_key_blob(path, , NULL, -1, KEY_ENCRYPTED);
if (!blob)
return -ENOMEM;
 
diff --git a/ndctl/util/keys.h b/ndctl/util/keys.h
index eab78d2f..9bc995ac 100644
--- a/ndctl/util/keys.h
+++ b/ndctl/util/keys.h
@@ -12,9 +12,15 @@ enum ndctl_key_type {
ND_ZERO_KEY,
 };
 
+enum key_type {
+   KEY_USER = 0,
+   KEY_TRUSTED,
+   KEY_ENCRYPTED,
+};
+
 #ifdef ENABLE_KEYUTILS
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd);
+   int dirfd, enum key_type key_type);
 int ndctl_dimm_setup_key(struct ndctl_dimm *dimm, const char *kek,
enum ndctl_key_type key_type);
 int ndctl_dimm_update_key(struct ndctl_dimm *dimm, const char *kek,
@@ -25,7 +31,7 @@ int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
 int ndctl_dimm_overwrite_key(struct ndctl_dimm *dimm);
 #else
 char *ndctl_load_key_blob(const char *path, int *size, const char *postfix,
-   int dirfd)
+   int dirfd, enum key_type key_type)
 {
return NULL;
 }

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


[PATCH 3/3] ndctl: add unit test for load-keys

2019-03-28 Thread Dave Jiang
Add to security.sh to test load-keys for user keys.

Signed-off-by: Dave Jiang 
---
 test/security.sh |   56 ++
 1 file changed, 52 insertions(+), 4 deletions(-)

diff --git a/test/security.sh b/test/security.sh
index 1b7a9a1a..7bd60293 100755
--- a/test/security.sh
+++ b/test/security.sh
@@ -6,8 +6,10 @@ rc=77
 dev=""
 id=""
 keypath="/etc/ndctl/keys"
-masterkey="nvdimm-master-test"
-masterpath="$keypath/$masterkey"
+masterkey="nvdimm-master"
+masterpath="$keypath/$masterkey.blob"
+backup_key=0
+backup_handle=0
 
 . ./common
 
@@ -32,6 +34,15 @@ setup_keys()
mkdir -p "$keypath"
fi
 
+   if [ -f "$masterpath" ]; then
+   mv "$masterpath" "$masterpath.bak"
+   $backup_key=1
+   fi
+   if [ -f "$keypath/tpm.handle" ]; then
+   mv "$keypath/tpm.handle" "$keypath/tmp.handle.bak"
+   $backup_handle=1
+   fi
+
dd if=/dev/urandom bs=1 count=32 2>/dev/null | keyctl padd user 
"$masterkey" @u
keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
 }
@@ -53,6 +64,12 @@ test_cleanup()
if [ -f $masterpath ]; then
rm -f "$masterpath"
fi
+   if [ "$backup_key" -eq 1 ]; then
+   mv "$masterpath.bak" "$masterpath"
+   fi
+   if [ "$backup_handle" -eq 1 ]; then
+   mv "$keypath/tpm.handle.bak" "$keypath/tmp.handle"
+   fi
 }
 
 lock_dimm()
@@ -188,6 +205,33 @@ test_5_security_freeze()
fi
 }
 
+test_6_load_keys()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   fi
+
+   $NDCTL load-keys
+
+   if keyctl search @u user "$masterkey"; then
+   echo "master key loaded"
+   else
+   echo "master key fail to loaded"
+   err "$LINENO"
+   fi
+
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   echo "dimm key loaded"
+   else
+   echo "dimm key failed to load"
+   err "$LINENO"
+   fi
+}
+
 check_min_kver "5.0" || do_skip "may lack security handling"
 uid="$(keyctl show | grep -Eo "_uid.[0-9]+" | head -1 | cut -d. -f2-)"
 if [ "$uid" -ne 0 ]; then
@@ -210,11 +254,15 @@ test_3_security_setup_and_erase
 echo "Test 4, unlock dimm"
 test_4_security_unlock
 
-# Freeze should always be run last because it locks security state and require
-# nfit_test module unload.
+# Freeze should always be run as last DIMM operation because it locks
+# security state and require nfit_test module unload.
 echo "Test 5, freeze security"
 test_5_security_freeze
 
+# this is purely on keyctl management and does not involve nvdimm
+echo "Test 6, test load-keys"
+test_6_load_keys
+
 test_cleanup
 _cleanup
 exit 0

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


[PATCH v5 2/2] libnvdimm/security, acpi/nfit: unify zero-key for all security commands

2019-03-27 Thread Dave Jiang
With zero-key defined, we can remove previous detection of key id 0 or null
key in order to deal with a zero-key situation. Syncing all security
commands to use the zero-key. Helper functions are introduced to return the
data that points to the actual key payload or the zero_key. This helps
uniformly handle the key material even with zero_key.

Signed-off-by: Dave Jiang 
---
v5:
- Updated commit message and header.
- Added helper functions for key payload management to support zero_key
  (Dan)
- Fixed up security unlock path as well. (Dan)

v4:
- Remove deprecated code to detect NULL key in acpi/nfit. (Dan)
v3:
- new patch. sync rest of the commands to use zero key. (Dan)

 drivers/acpi/nfit/intel.c |   10 ++--
 drivers/nvdimm/security.c |  117 +++--
 2 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
index f70de71f79d6..cddd0fcf622c 100644
--- a/drivers/acpi/nfit/intel.c
+++ b/drivers/acpi/nfit/intel.c
@@ -122,9 +122,8 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
if (!test_bit(cmd, _mem->dsm_mask))
return -ENOTTY;
 
-   if (old_data)
-   memcpy(nd_cmd.cmd.old_pass, old_data->data,
-   sizeof(nd_cmd.cmd.old_pass));
+   memcpy(nd_cmd.cmd.old_pass, old_data->data,
+   sizeof(nd_cmd.cmd.old_pass));
memcpy(nd_cmd.cmd.new_pass, new_data->data,
sizeof(nd_cmd.cmd.new_pass));
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, _cmd, sizeof(nd_cmd), NULL);
@@ -336,9 +335,8 @@ static int __maybe_unused intel_security_overwrite(struct 
nvdimm *nvdimm,
 
/* flush all cache before we erase DIMM */
nvdimm_invalidate_cache();
-   if (nkey)
-   memcpy(nd_cmd.cmd.passphrase, nkey->data,
-   sizeof(nd_cmd.cmd.passphrase));
+   memcpy(nd_cmd.cmd.passphrase, nkey->data,
+   sizeof(nd_cmd.cmd.passphrase));
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, _cmd, sizeof(nd_cmd), NULL);
if (rc < 0)
return rc;
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 6bea6852bf27..a570f2263a42 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -77,6 +77,16 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
return key;
 }
 
+static const void *nvdimm_get_key_payload(struct nvdimm *nvdimm,
+   struct key **key)
+{
+   *key = nvdimm_request_key(nvdimm);
+   if (!*key)
+   return zero_key;
+
+   return key_data(*key);
+}
+
 static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm,
key_serial_t id, int subclass)
 {
@@ -107,36 +117,57 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm 
*nvdimm,
return key;
 }
 
-static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm)
+static const void *nvdimm_get_user_key_payload(struct nvdimm *nvdimm,
+   key_serial_t id, int subclass, struct key **key)
+{
+   *key = NULL;
+   if (id == 0) {
+   if (subclass == NVDIMM_BASE_KEY)
+   return zero_key;
+   else
+   return NULL;
+   }
+
+   *key = nvdimm_lookup_user_key(nvdimm, id, subclass);
+   if (!*key)
+   return NULL;
+
+   return key_data(*key);
+}
+
+
+static int nvdimm_key_revalidate(struct nvdimm *nvdimm)
 {
struct key *key;
int rc;
+   const void *data;
 
if (!nvdimm->sec.ops->change_key)
-   return NULL;
+   return -EOPNOTSUPP;
 
-   key = nvdimm_request_key(nvdimm);
-   if (!key)
-   return NULL;
+   data = nvdimm_get_key_payload(nvdimm, );
 
/*
 * Send the same key to the hardware as new and old key to
 * verify that the key is good.
 */
-   rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key),
-   key_data(key), NVDIMM_USER);
+   rc = nvdimm->sec.ops->change_key(nvdimm, data, data, NVDIMM_USER);
if (rc < 0) {
nvdimm_put_key(key);
-   key = NULL;
+   return rc;
}
-   return key;
+
+   nvdimm_put_key(key);
+   nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
+   return 0;
 }
 
 static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
 {
struct device *dev = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key = NULL;
+   struct key *key;
+   const void *data;
int rc;
 
/* The bus lock should be held at the top level of the call stack */
@@ -162,16 +193,11 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
if (!key_revalidate)
return 0;
 
- 

[PATCH v5 1/2] libnvdimm/security: provide fix for secure-erase to use zero-key

2019-03-27 Thread Dave Jiang
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 
---
v5:
- Updated commit message and header. (Dan)

v4: No change

v3:
- Add note in commit header about syncing zero key usage. (Dan)

v2:
- Make patch header explicitly zero key (Dan)
- Declare global static zero key (Dan)
- Make nfit_test explicitly test zero key (Dan)

 drivers/nvdimm/security.c|   17 -
 tools/testing/nvdimm/test/nfit.c |   11 +--
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..6bea6852bf27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -22,6 +22,8 @@ static bool key_revalidate = true;
 module_param(key_revalidate, bool, 0444);
 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)
 {
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 = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
return -EOPNOTSUPP;
}
 
-   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
-   if (!key)
-   return -ENOKEY;
+   if (keyid != 0) {
+   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
+   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),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..cad719876ef4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
 
 static struct gen_pool *nfit_pool;
 
+static const char zero_key[NVDIMM_PASSPHRASE_LEN];
+
 static struct nfit_test *to_nfit_test(struct 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 = >pdev.dev;
struct nfit_test_sec *sec = _sec_info[dimm];
 
-   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
-   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
+   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
dev_dbg(dev, "secure erase: wrong security state\n");
} 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;
dev_dbg(dev, "secure erase: wrong passphrase\n");
} 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->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
sec->state = 0;

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


[PATCH v4 2/2] libnvdimm/security, acpi/nfit: move other seucrity commands to utilize zero key

2019-03-26 Thread Dave Jiang
Sync update passphrase and overwrite to utilize the the same mechansim for
zero key.

Signed-off-by: Dave Jiang 
---
v4:
- Remove deprecated code to detect NULL key in acpi/nfit. (Dan)
v3:
- new patch. sync rest of the commands to use zero key. (Dan)

 drivers/acpi/nfit/intel.c |   10 --
 drivers/nvdimm/security.c |   28 +++-
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/nfit/intel.c b/drivers/acpi/nfit/intel.c
index f70de71f79d6..cddd0fcf622c 100644
--- a/drivers/acpi/nfit/intel.c
+++ b/drivers/acpi/nfit/intel.c
@@ -122,9 +122,8 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
if (!test_bit(cmd, _mem->dsm_mask))
return -ENOTTY;
 
-   if (old_data)
-   memcpy(nd_cmd.cmd.old_pass, old_data->data,
-   sizeof(nd_cmd.cmd.old_pass));
+   memcpy(nd_cmd.cmd.old_pass, old_data->data,
+   sizeof(nd_cmd.cmd.old_pass));
memcpy(nd_cmd.cmd.new_pass, new_data->data,
sizeof(nd_cmd.cmd.new_pass));
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, _cmd, sizeof(nd_cmd), NULL);
@@ -336,9 +335,8 @@ static int __maybe_unused intel_security_overwrite(struct 
nvdimm *nvdimm,
 
/* flush all cache before we erase DIMM */
nvdimm_invalidate_cache();
-   if (nkey)
-   memcpy(nd_cmd.cmd.passphrase, nkey->data,
-   sizeof(nd_cmd.cmd.passphrase));
+   memcpy(nd_cmd.cmd.passphrase, nkey->data,
+   sizeof(nd_cmd.cmd.passphrase));
rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, _cmd, sizeof(nd_cmd), NULL);
if (rc < 0)
return rc;
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index 6bea6852bf27..429cb3cbc1c3 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -235,8 +235,9 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned 
int keyid,
 {
struct device *dev = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key, *newkey;
+   struct key *key = NULL, *newkey;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -251,13 +252,13 @@ int nvdimm_security_update(struct nvdimm *nvdimm, 
unsigned int keyid,
return -EIO;
}
 
-   if (keyid == 0)
-   key = NULL;
-   else {
+   if (keyid != 0) {
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
if (!key)
return -ENOKEY;
-   }
+   data = key_data(key);
+   } else
+   data = zero_key;
 
newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY);
if (!newkey) {
@@ -265,8 +266,8 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned 
int keyid,
return -ENOKEY;
}
 
-   rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL,
-   key_data(newkey), pass_type);
+   rc = nvdimm->sec.ops->change_key(nvdimm, data, key_data(newkey),
+   pass_type);
dev_dbg(dev, "key: %d %d update%s: %s\n",
key_serial(key), key_serial(newkey),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
@@ -344,8 +345,9 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, 
unsigned int keyid)
 {
struct device *dev = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -375,15 +377,15 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, 
unsigned int keyid)
return -EBUSY;
}
 
-   if (keyid == 0)
-   key = NULL;
-   else {
+   if (keyid != 0) {
key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
if (!key)
return -ENOKEY;
-   }
+   data = key_data(key);
+   } else
+   data = zero_key;
 
-   rc = nvdimm->sec.ops->overwrite(nvdimm, key ? key_data(key) : NULL);
+   rc = nvdimm->sec.ops->overwrite(nvdimm, data);
dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key),
rc == 0 ? "success" : "fail");
 

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


[PATCH v4 1/2] libnvdimm/security: Support a zero-key for secure-erase

2019-03-26 Thread Dave Jiang
Adding support to allow secure erase to happen when security state is not
enabled. Key data of 0's will be passed in.

Some other security commands already use zero keys. This is to unifiy
semantics cross commands with respect to using zero keys.

Signed-off-by: Dave Jiang 
---
v4: No change

v3:
- Add note in commit header about syncing zero key usage. (Dan)

v2:
- Make patch header explicitly zero key (Dan)
- Declare global static zero key (Dan)
- Make nfit_test explicitly test zero key (Dan)

 drivers/nvdimm/security.c|   17 -
 tools/testing/nvdimm/test/nfit.c |   11 +--
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..6bea6852bf27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -22,6 +22,8 @@ static bool key_revalidate = true;
 module_param(key_revalidate, bool, 0444);
 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)
 {
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 = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
return -EOPNOTSUPP;
}
 
-   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
-   if (!key)
-   return -ENOKEY;
+   if (keyid != 0) {
+   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
+   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),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..cad719876ef4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
 
 static struct gen_pool *nfit_pool;
 
+static const char zero_key[NVDIMM_PASSPHRASE_LEN];
+
 static struct nfit_test *to_nfit_test(struct 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 = >pdev.dev;
struct nfit_test_sec *sec = _sec_info[dimm];
 
-   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
-   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
+   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
dev_dbg(dev, "secure erase: wrong security state\n");
} 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;
dev_dbg(dev, "secure erase: wrong passphrase\n");
} 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->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
sec->state = 0;

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


[PATCH v3 1/2] libnvdimm/security: Support a zero-key for secure-erase

2019-03-22 Thread Dave Jiang
Adding support to allow secure erase to happen when security state is not
enabled. Key data of 0's will be passed in.

Some other security commands already use zero keys. This is to unifiy
semantics cross commands with respect to using zero keys.

Signed-off-by: Dave Jiang 
---

v3:
- Add note in commit header about syncing zero key usage. (Dan)

v2:
- Make patch header explicitly zero key (Dan)
- Declare global static zero key (Dan)
- Make nfit_test explicitly test zero key (Dan)

 drivers/nvdimm/security.c|   17 -
 tools/testing/nvdimm/test/nfit.c |   11 +--
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..6bea6852bf27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -22,6 +22,8 @@ static bool key_revalidate = true;
 module_param(key_revalidate, bool, 0444);
 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)
 {
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 = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
return -EOPNOTSUPP;
}
 
-   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
-   if (!key)
-   return -ENOKEY;
+   if (keyid != 0) {
+   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
+   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),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..cad719876ef4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
 
 static struct gen_pool *nfit_pool;
 
+static const char zero_key[NVDIMM_PASSPHRASE_LEN];
+
 static struct nfit_test *to_nfit_test(struct 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 = >pdev.dev;
struct nfit_test_sec *sec = _sec_info[dimm];
 
-   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
-   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
+   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
dev_dbg(dev, "secure erase: wrong security state\n");
} 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;
dev_dbg(dev, "secure erase: wrong passphrase\n");
} 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->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
sec->state = 0;

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


[PATCH 2/2] ndctl: fix typo mistake for ndctl-sanitize-dimm

2019-03-22 Thread Dave Jiang
correct master_passphrase to master-passphrase

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index ebf4b995..91abf471 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -53,7 +53,7 @@ include::xable-dimm-options.txt[]
tens of minutes to many hours.
 
 -m::
---master_passphrase::
+--master-passphrase::
Indicate that we are using the master passphrase to perform the erase.
This only is applicable to the 'crypto-erase' option.
 

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


[PATCH v2] ndctl: add support to allow zero key for secure erase

2019-03-22 Thread Dave Jiang
Providing a way for crypto-erase to pass in a key that is with 0's as
payload.

Signed-off-by: Dave Jiang 
---

v2:
- Make zero key option explicit with -z parameter. Otherwise we will look
  for a key. (Dan)

 Documentation/ndctl/ndctl-sanitize-dimm.txt |4 
 ndctl/dimm.c|   16 +---
 ndctl/util/keys.c   |   12 +++-
 ndctl/util/keys.h   |1 +
 4 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 7f57a115..797820dd 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -56,6 +56,10 @@ include::xable-dimm-options.txt[]
Indicate that we are using the master passphrase to perform the erase.
This only is applicable to the 'crypto-erase' option.
 
+-z::
+--zero-key::
+   Passing in a key with payload that is just 0's.
+
 --verbose::
 Emit debug messages.
 
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index cc0bec04..b2b09b6a 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -49,6 +49,7 @@ static struct parameters {
const char *kek;
bool crypto_erase;
bool overwrite;
+   bool zero_key;
bool master_pass;
bool force;
bool json;
@@ -904,6 +905,7 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
struct action_context *actx)
 {
int rc;
+   enum ndctl_key_type key_type;
 
if (ndctl_dimm_get_security(dimm) < 0) {
error("%s: security operation not supported\n",
@@ -927,8 +929,14 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm, param.master_pass ?
-   ND_MASTER_KEY : ND_USER_KEY);
+   if (param.zero_key)
+   key_type = ND_ZERO_KEY;
+   else if (param.master_pass)
+   key_type = ND_MASTER_KEY;
+   else
+   key_type = ND_USER_KEY;
+
+   rc = ndctl_dimm_secure_erase_key(dimm, key_type);
if (rc < 0)
return rc;
}
@@ -1057,7 +1065,9 @@ OPT_STRING('k', "key-handle", , "key-handle", \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('z', "zero-key", _key, \
+   "pass in a zero key")
 
 #define MASTER_OPTIONS() \
 OPT_BOOLEAN('m', "master-passphrase", _pass, \
diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index c1f2e843..c091cc5c 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -612,17 +612,19 @@ int ndctl_dimm_remove_key(struct ndctl_dimm *dimm)
 int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
enum ndctl_key_type key_type)
 {
-   key_serial_t key;
+   key_serial_t key = 0;
int rc;
 
-   key = check_dimm_key(dimm, true, key_type);
-   if (key < 0)
-   return key;
+   if (key_type != ND_ZERO_KEY) {
+   key = check_dimm_key(dimm, true, key_type);
+   if (key < 0)
+   return key;
+   }
 
if (key_type == ND_MASTER_KEY)
rc = run_key_op(dimm, key, ndctl_dimm_master_secure_erase,
"master crypto erase");
-   else if (key_type == ND_USER_KEY)
+   else if (key_type == ND_USER_KEY || key_type == ND_ZERO_KEY)
rc = run_key_op(dimm, key, ndctl_dimm_secure_erase,
"crypto erase");
else
diff --git a/ndctl/util/keys.h b/ndctl/util/keys.h
index 30687a13..eab78d2f 100644
--- a/ndctl/util/keys.h
+++ b/ndctl/util/keys.h
@@ -9,6 +9,7 @@ enum ndctl_key_type {
ND_USER_OLD_KEY,
ND_MASTER_KEY,
ND_MASTER_OLD_KEY,
+   ND_ZERO_KEY,
 };
 
 #ifdef ENABLE_KEYUTILS

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


[PATCH v2] libnvdimm/security: Support a zero-key for secure-erase

2019-03-22 Thread Dave Jiang
Adding support to allow secure erase to happen when security state is not
enabled. Key data of 0's will be passed in.

Signed-off-by: Dave Jiang 
---

v2:
- Make patch header explicitly zero key (Dan)
- Declare global static zero key (Dan)
- Make nfit_test explicitly test zero key (Dan)

 drivers/nvdimm/security.c|   17 -
 tools/testing/nvdimm/test/nfit.c |   11 +--
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..6bea6852bf27 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -22,6 +22,8 @@ static bool key_revalidate = true;
 module_param(key_revalidate, bool, 0444);
 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)
 {
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 = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   const void *data;
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -319,11 +322,15 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
return -EOPNOTSUPP;
}
 
-   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
-   if (!key)
-   return -ENOKEY;
+   if (keyid != 0) {
+   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
+   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),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..cad719876ef4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -225,6 +225,8 @@ static struct workqueue_struct *nfit_wq;
 
 static struct gen_pool *nfit_pool;
 
+static const char zero_key[NVDIMM_PASSPHRASE_LEN];
+
 static struct nfit_test *to_nfit_test(struct 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 = >pdev.dev;
struct nfit_test_sec *sec = _sec_info[dimm];
 
-   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
-   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
+   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
dev_dbg(dev, "secure erase: wrong security state\n");
} 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;
dev_dbg(dev, "secure erase: wrong passphrase\n");
} 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->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
sec->state = 0;

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


Re: [PATCH] nvdimm: security: allow secure erase to execute without key

2019-03-22 Thread Dave Jiang



On 3/22/19 2:43 PM, Dan Williams wrote:
> On Fri, Mar 22, 2019 at 2:33 PM Dave Jiang  wrote:
>>
>> Adding support to allow secure erase to happen when security state is not
>> enabled. Key data of 0's will be passed in.
> 
> I think I want to change this wording and patch title to say
> "libnvdimm/security: Support a zero-key for secure-erase". Because we
> are still passing a key and the kernel interface requires the key-id
> parameter, we're just arranging for a special key to be used.
> 
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>  drivers/nvdimm/security.c|   17 -
>>  tools/testing/nvdimm/test/nfit.c |3 +--
>>  2 files changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
>> index f8bb746a549f..b7bd26030964 100644
>> --- a/drivers/nvdimm/security.c
>> +++ b/drivers/nvdimm/security.c
>> @@ -286,8 +286,9 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, 
>> unsigned int keyid,
>>  {
>> struct device *dev = >dev;
>> struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
>> -   struct key *key;
>> +   struct key *key = NULL;
>> int rc;
>> +   char *data, dummy_key[NVDIMM_PASSPHRASE_LEN];
> 
> Let's make this
> 
> static const char zero_key[NVDIMM_PASSPHRASE_LEN];
> 
> ...and make it global.
> 
>>
>> /* The bus lock should be held at the top level of the call stack */
>> lockdep_assert_held(_bus->reconfig_mutex);
>> @@ -319,11 +320,17 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, 
>> unsigned int keyid,
>> return -EOPNOTSUPP;
>> }
>>
>> -   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
>> -   if (!key)
>> -   return -ENOKEY;
>> +   if (keyid != 0) {
>> +   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
>> +   if (!key)
>> +   return -ENOKEY;
>> +   data = key_data(key);
>> +   } else {
>> +   memset(dummy_key, 0, NVDIMM_PASSPHRASE_LEN);
> 
> ...with the above change no need to do a memset.
> 
>> +   data = dummy_key;
> 
> There may be hardware that actually expects zeroes so I'd rather be
> explicit, because if it was truly "dummy" there would be no need to
> initialize it.
> 
>> +   }
>>
>> -   rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type);
>> +   rc = nvdimm->sec.ops->erase(nvdimm, (void *)data, pass_type);
>> dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
>> pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
>> rc == 0 ? "success" : "fail");
>> diff --git a/tools/testing/nvdimm/test/nfit.c 
>> b/tools/testing/nvdimm/test/nfit.c
>> index b579f962451d..9351a81ea945 100644
>> --- a/tools/testing/nvdimm/test/nfit.c
>> +++ b/tools/testing/nvdimm/test/nfit.c
>> @@ -1059,8 +1059,7 @@ static int nd_intel_test_cmd_secure_erase(struct 
>> nfit_test *t,
>> struct device *dev = >pdev.dev;
>> struct nfit_test_sec *sec = _sec_info[dimm];
>>
>> -   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
>> -   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
>> +   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
> 
> What does this have to do with the new zero-key?
> 
Because otherwise we will reject the op when security is not enabled.
The whole point of this was to support secure erase when security is not
enabled.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH] dsactl: add support to allow keyless secure erase

2019-03-22 Thread Dave Jiang
When security is not enabled, we reject secure erase currently. Add
support to allow secure erase to occur without key.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |2 ++
 ndctl/util/keys.c   |   16 +++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 7f57a115..d9450dd3 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -33,6 +33,8 @@ erase. The default is 'crypto-erase', but additionally, an 
'overwrite' option
 is available which overwrites not only the data area, but also the label area,
 thus losing record of any namespaces the given NVDIMM participates in.
 
+It is possible to crypto-erase or overwrite without a key.
+
 OPTIONS
 ---
 ::
diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index c1f2e843..82c16539 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -612,12 +612,18 @@ int ndctl_dimm_remove_key(struct ndctl_dimm *dimm)
 int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
enum ndctl_key_type key_type)
 {
-   key_serial_t key;
+   key_serial_t key = 0;
int rc;
+   enum ndctl_security_state state;
 
-   key = check_dimm_key(dimm, true, key_type);
-   if (key < 0)
-   return key;
+   state = ndctl_dimm_get_security(dimm);
+
+   if (key_type != ND_MASTER_KEY &&
+   state != NDCTL_SECURITY_DISABLED) {
+   key = check_dimm_key(dimm, true, key_type);
+   if (key < 0)
+   return key;
+   }
 
if (key_type == ND_MASTER_KEY)
rc = run_key_op(dimm, key, ndctl_dimm_master_secure_erase,
@@ -630,7 +636,7 @@ int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
if (rc < 0)
return rc;
 
-   if (key_type == ND_USER_KEY)
+   if (key_type == ND_USER_KEY && key != 0)
return discard_key(dimm);
 
return 0;

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


[PATCH] nvdimm: security: allow secure erase to execute without key

2019-03-22 Thread Dave Jiang
Adding support to allow secure erase to happen when security state is not
enabled. Key data of 0's will be passed in.

Signed-off-by: Dave Jiang 
---
 drivers/nvdimm/security.c|   17 -
 tools/testing/nvdimm/test/nfit.c |3 +--
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index f8bb746a549f..b7bd26030964 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -286,8 +286,9 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
 {
struct device *dev = >dev;
struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
-   struct key *key;
+   struct key *key = NULL;
int rc;
+   char *data, dummy_key[NVDIMM_PASSPHRASE_LEN];
 
/* The bus lock should be held at the top level of the call stack */
lockdep_assert_held(_bus->reconfig_mutex);
@@ -319,11 +320,17 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned 
int keyid,
return -EOPNOTSUPP;
}
 
-   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
-   if (!key)
-   return -ENOKEY;
+   if (keyid != 0) {
+   key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY);
+   if (!key)
+   return -ENOKEY;
+   data = key_data(key);
+   } else {
+   memset(dummy_key, 0, NVDIMM_PASSPHRASE_LEN);
+   data = dummy_key;
+   }
 
-   rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type);
+   rc = nvdimm->sec.ops->erase(nvdimm, (void *)data, pass_type);
dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key),
pass_type == NVDIMM_MASTER ? "(master)" : "(user)",
rc == 0 ? "success" : "fail");
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..9351a81ea945 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -1059,8 +1059,7 @@ static int nd_intel_test_cmd_secure_erase(struct 
nfit_test *t,
struct device *dev = >pdev.dev;
struct nfit_test_sec *sec = _sec_info[dimm];
 
-   if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) ||
-   (sec->state & ND_INTEL_SEC_STATE_FROZEN)) {
+   if (sec->state & ND_INTEL_SEC_STATE_FROZEN) {
nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE;
dev_dbg(dev, "secure erase: wrong security state\n");
} else if (memcmp(nd_cmd->passphrase, sec->passphrase,

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


Re: [PATCH 3/6] libnvdimm/security: Drop direct dependency on key_type_encrypted

2019-03-19 Thread Dave Jiang



On 3/18/19 11:06 PM, Dan Williams wrote:
> Lookup the key type by name and protect libnvdimm from encrypted_keys.ko
> module load failures.
> 
> Cc: Vishal Verma 
> Cc: Dave Jiang 
> Cc: Keith Busch 
> Cc: Ira Weiny 
> Signed-off-by: Dan Williams 

Reviewed-by: Dave Jiang 

> ---
>  drivers/nvdimm/security.c |   11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
> index f8bb746a549f..7f9e412f743a 100644
> --- a/drivers/nvdimm/security.c
> +++ b/drivers/nvdimm/security.c
> @@ -48,12 +48,17 @@ static void nvdimm_put_key(struct key *key)
>  static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
>  {
>   struct key *key = NULL;
> + struct key_type *type;
>   static const char NVDIMM_PREFIX[] = "nvdimm:";
>   char desc[NVDIMM_KEY_DESC_LEN + sizeof(NVDIMM_PREFIX)];
>   struct device *dev = >dev;
>  
>   sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id);
> - key = request_key(_type_encrypted, desc, "");
> + type = key_type_lookup("encrypted");
> + if (IS_ERR(type))
> + return (struct key *) type;
> +
> + key = request_key(type, desc, "");
>   if (IS_ERR(key)) {
>   if (PTR_ERR(key) == -ENOKEY)
>   dev_dbg(dev, "request_key() found no key\n");
> @@ -88,7 +93,7 @@ static struct key *nvdimm_lookup_user_key(struct nvdimm 
> *nvdimm,
>   return NULL;
>  
>   key = key_ref_to_ptr(keyref);
> - if (key->type != _type_encrypted) {
> + if (strcmp(key->type->name, "encrypted") != 0) {
>   key_put(key);
>   return NULL;
>   }
> @@ -452,3 +457,5 @@ void nvdimm_security_overwrite_query(struct work_struct 
> *work)
>   __nvdimm_security_overwrite_query(nvdimm);
>   nvdimm_bus_unlock(>dev);
>  }
> +
> +MODULE_SOFTDEP("pre: encrypted_keys");
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH] tools/testing/nvdimm: retain security state after overwrite

2019-03-11 Thread Dave Jiang
Overwrite retains the security state after completion of operation.
Fix nfit_test to reflect this.

Fixes: 926f74802cb ("tools/testing/nvdimm: Add overwrite support for
nfit_test")

Signed-off-by: Dave Jiang 
---
 tools/testing/nvdimm/test/nfit.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index b579f962451d..c7c19ca7588f 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -146,6 +146,7 @@ static int dimm_fail_cmd_code[ARRAY_SIZE(handle)];
 struct nfit_test_sec {
u8 state;
u8 ext_state;
+   u8 old_state;
u8 passphrase[32];
u8 master_passphrase[32];
u64 overwrite_end_time;
@@ -1093,7 +1094,7 @@ static int nd_intel_test_cmd_overwrite(struct nfit_test 
*t,
return 0;
}
 
-   memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE);
+   sec->old_state = sec->state;
sec->state = ND_INTEL_SEC_STATE_OVERWRITE;
dev_dbg(dev, "overwrite progressing.\n");
sec->overwrite_end_time = get_jiffies_64() + 5 * HZ;
@@ -1115,7 +1116,8 @@ 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->state = sec->old_state;
+   sec->old_state = 0;
sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED;
dev_dbg(dev, "overwrite is complete\n");
} else

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


[PATCH] ndctl: update security handling post overwrite

2019-03-11 Thread Dave Jiang
The security state after overwrite completion is expected to remain the
same as before overwrite. Current implementation assumed that overwrite
would remove the security state and therefore removing the keys. Update
so security keys are not removed.

Dave Jiang 
---
 ndctl/util/keys.c |3 ---
 1 file changed, 3 deletions(-)

diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index c1f2e843..f315802c 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -650,8 +650,5 @@ int ndctl_dimm_overwrite_key(struct ndctl_dimm *dimm)
if (rc < 0)
return rc;
 
-   if (key > 0)
-   return discard_key(dimm);
-
return 0;
 }

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


Re: [ndctl PATCH] ndctl: fix ndctl linking with libkeyutils

2019-02-05 Thread Dave Jiang



On 2/5/19 2:47 PM, Vishal Verma wrote:
> From: Piotr Balcer 
> 
> Compilation on Ubuntu 18.04 fails with:
> 
>   /usr/bin/ld: util/keys.o: undefined reference to symbol 
> 'keyctl_read_alloc@@KEYUTILS_0.3'
>   /lib/x86_64-linux-gnu/libkeyutils.so.1: error adding symbols: DSO missing 
> from command line
> 
> Seems like libkeyutils is incorrectly linked against libndctl,
> where in reality it's the ndctl application that uses keyutils.
> 
> Cc: Dave Jiang 
> Fixes: 86b078b44275 ("ndctl: add passphrase management commands")
> Signed-off-by: Piotr Balcer 
> Signed-off-by: Vishal Verma 

Ah yeah it used to be in libndctl, but in the last round of changes it
was moved to ndctl/utils.

Reviewed-by: Dave Jiang 

> ---
>  ndctl/Makefile.am | 4 
>  ndctl/lib/Makefile.am | 4 
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
> index 3287dbb..502271e 100644
> --- a/ndctl/Makefile.am
> +++ b/ndctl/Makefile.am
> @@ -47,6 +47,10 @@ ndctl_LDADD =\
>   $(KMOD_LIBS) \
>   $(JSON_LIBS)
>  
> +if ENABLE_KEYUTILS
> +ndctl_LDADD += -lkeyutils
> +endif
> +
>  if ENABLE_TEST
>  ndctl_SOURCES += ../test/libndctl.c \
>../test/dsm-fail.c \
> diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
> index 99eaae0..7797039 100644
> --- a/ndctl/lib/Makefile.am
> +++ b/ndctl/lib/Makefile.am
> @@ -30,10 +30,6 @@ libndctl_la_LIBADD =\
>   $(UUID_LIBS) \
>   $(KMOD_LIBS)
>  
> -if ENABLE_KEYUTILS
> -libndctl_la_LIBADD += -lkeyutils
> -endif
> -
>  EXTRA_DIST += libndctl.sym
>  
>  libndctl_la_LDFLAGS = $(AM_LDFLAGS) \
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v10 10/12] ndctl: master phassphrase management support

2019-01-24 Thread Dave Jiang
Adding master passphrase enabling and update to ndctl. This is a new
feature from Intel DSM v1.8.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-setup-passphrase.txt  |5 +
 Documentation/ndctl/ndctl-update-passphrase.txt |6 +
 ndctl/dimm.c|   13 ++-
 ndctl/lib/dimm.c|9 ++
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|2 
 ndctl/util/keys.c   |  117 +--
 ndctl/util/keys.h   |   12 ++
 8 files changed, 129 insertions(+), 36 deletions(-)

diff --git a/Documentation/ndctl/ndctl-setup-passphrase.txt 
b/Documentation/ndctl/ndctl-setup-passphrase.txt
index 1594f110..613e17a1 100644
--- a/Documentation/ndctl/ndctl-setup-passphrase.txt
+++ b/Documentation/ndctl/ndctl-setup-passphrase.txt
@@ -40,6 +40,11 @@ include::xable-dimm-options.txt[]
i.e. trusted:nvdimm-master
This key is expected to be loaded in the kernel's user keyring.
 
+-m::
+--master-passphrase::
+   Indicates that we are managing the master passphrase instead of the
+   user passphrase.
+
 -v::
 --verbose::
 Emit debug messages for the namespace check process.
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
index 05573968..8b5fc812 100644
--- a/Documentation/ndctl/ndctl-update-passphrase.txt
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -40,10 +40,14 @@ include::xable-dimm-options.txt[]
This parameter is optional. If none provided, ndctl will determine
the current key handle from the encrypted key for the NVDIMM.
 
+-m::
+--master-passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase.
+
 -v::
 --verbose::
 Emit debug messages for the namespace check process.
-
 include::../copyright.txt[]
 
 SEE ALSO:
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index fb16e9c8..c5c4a6cb 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -49,6 +49,7 @@ static struct parameters {
const char *kek;
bool crypto_erase;
bool overwrite;
+   bool master_pass;
bool force;
bool json;
bool verbose;
@@ -852,7 +853,8 @@ static int action_passphrase_setup(struct ndctl_dimm *dimm,
if (!param.kek)
return -EINVAL;
 
-   return ndctl_dimm_setup_key(dimm, param.kek);
+   return ndctl_dimm_setup_key(dimm, param.kek,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_update(struct ndctl_dimm *dimm,
@@ -864,7 +866,8 @@ static int action_passphrase_update(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_update_key(dimm, param.kek);
+   return ndctl_dimm_update_key(dimm, param.kek,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_remove(struct ndctl_dimm *dimm,
@@ -1049,6 +1052,10 @@ OPT_BOOLEAN('c', "crypto-erase", _erase, \
 OPT_BOOLEAN('o', "overwrite", , \
"overwrite a dimm")
 
+#define MASTER_OPTIONS() \
+OPT_BOOLEAN('m', "master-passphrase", _pass, \
+   "use master passphrase")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1081,11 +1088,13 @@ static const struct option init_options[] = {
 static const struct option key_options[] = {
BASE_OPTIONS(),
KEY_OPTIONS(),
+   MASTER_OPTIONS(),
 };
 
 static const struct option sanitize_options[] = {
BASE_OPTIONS(),
SANITIZE_OPTIONS(),
+   MASTER_OPTIONS(),
OPT_END(),
 };
 
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 150e337a..5c65d171 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -763,3 +763,12 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
ndctl_dimm *dimm)
close(fd);
return rc;
 }
+
+NDCTL_EXPORT int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
+   long ckey, long nkey)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 7bd4ba59..c9e530ba 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -397,4 +397,5 @@ global:
ndctl_dimm_secure_erase;
ndctl_dimm_overwrite;
ndctl_dimm_wait_overwrite;
+   ndctl_dimm_update_master_passphrase;
 } LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index f767d637..893e92e4 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -705,6 +705,8 @@ int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm);
 int ndctl_dimm_secure_erase(struct ndctl_dimm *dimm, long key);

[PATCH v10 09/12] ndctl: add wait-overwrite support

2019-01-24 Thread Dave Jiang
Add a blocking 'wait-overwrite' command to ndctl to let a user wait for an
overwrite operation on a dimm to complete.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 ++
 ndctl/builtin.h  |1 
 ndctl/dimm.c |   27 +
 ndctl/lib/dimm.c |   78 ++
 ndctl/lib/libndctl.sym   |1 
 ndctl/libndctl.h |1 
 ndctl/ndctl.c|1 
 8 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index f64619b0..2593dbdc 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -53,7 +53,8 @@ man1_MANS = \
ndctl-remove-passphrase.1 \
ndctl-freeze-security.1 \
ndctl-sanitize-dimm.1 \
-   ndctl-load-keys.1
+   ndctl-load-keys.1 \
+   ndctl-wait-overwrite.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-wait-overwrite.txt 
b/Documentation/ndctl/ndctl-wait-overwrite.txt
new file mode 100644
index ..5d4c72ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-wait-overwrite.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-wait-overwrite(1)
+===
+
+NAME
+
+ndctl-wait-overwrite - wait for nvdimm overwrite operation to complete
+
+SYNOPSIS
+
+[verse]
+'ndctl wait-overwrite'  []
+
+DESCRIPTION
+---
+The kernel provides a POLL(2) capable sysfs file ('security') to indicate
+the state of overwrite. The 'ndctl wait-overwrite' operation waits for
+a change in the state of the 'security' file across all specified dimms.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Emit debug messages for the overwrite wait process
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+linkndctl:ndctl-sanitize-dimm[1]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 733f41a5..60c3623f 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -38,4 +38,5 @@ int cmd_passphrase_remove(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_wait_overwrite(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index da940843..fb16e9c8 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -932,6 +932,24 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return 0;
 }
 
+static int action_wait_overwrite(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_wait_overwrite(dimm);
+   if (rc == 1)
+   printf("%s: overwrite completed.\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1356,3 +1374,12 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_overwrite(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_wait_overwrite,
+   base_options,
+   "ndctl wait-overwrite  [..] 
[]");
+
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index d7b70ebf..150e337a 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "private.h"
 
 static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
@@ -685,3 +686,80 @@ NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "overwrite %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   struct pollfd fds;
+   char buf[SYSFS_ATTR_SIZE];
+   int fd = 0, rc;
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(

[PATCH v10 08/12] ndctl: add overwrite operation support

2019-01-24 Thread Dave Jiang
Add support for overwrite to libndctl. The operation will be triggered
by the sanitize-dimm command with -o switch. This will initiate the request
to wipe the entire nvdimm. Success return of the command only indicate
overwrite has started and does not indicate completion of overwrite.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   26 +++
 ndctl/dimm.c|   46 +++
 ndctl/lib/dimm.c|8 +
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|1 +
 ndctl/util/keys.c   |   33 ---
 ndctl/util/keys.h   |6 
 7 files changed, 101 insertions(+), 20 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 633498ef..b0b1ae21 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -5,7 +5,7 @@ ndctl-sanitize-dimm(1)
 
 NAME
 
-ndctl-sanitize-dimm - Perform a cryptographic destruction of the contents of 
the given NVDIMM(s).
+ndctl-sanitize-dimm - Perform a cryptographic destruction or overwrite of the 
contents of the given NVDIMM(s).
 
 SYNOPSIS
 
@@ -14,19 +14,29 @@ SYNOPSIS
 
 DESCRIPTION
 ---
-Search the user key ring for the associated NVDIMM. If not found,
-attempt to load the key blob from the default location. The sanitize
-operation scrambles the data and info-blocks, but it does not touch
-the namespace labels. The user should expect namespaces to revert to raw mode
-after the region is next enabled following the operation. Security is disabled
-for the dimm after operation and ndctl will remove the key from the key ring
-and delete the associated key blob file.
+Two different sanitize methods are supported. One is the crypto-erase, which
+is the default method, and the other is overwrite the NVDIMM. ndctl will
+search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location.
+Security is disabled for the dimm after operation and ndctl will remove
+the key from the key ring and delete the associated key blob file.
 
 OPTIONS
 ---
 ::
 include::xable-dimm-options.txt[]
 
+-c::
+--crypto-erase::
+   Replace the media encryption key causing all existing data to read as
+   cipher text with the new key. This does not change label data.
+   The user should expect namespaces to revert to raw mode
+   after the region is next enabled following the operation.
+
+-o::
+--ovewrite::
+   Wipe the entire DIMM, including label data. Can take significant time.
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index e7872f52..da940843 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,8 @@ static struct parameters {
const char *infile;
const char *labelversion;
const char *kek;
+   bool crypto_erase;
+   bool overwrite;
bool force;
bool json;
bool verbose;
@@ -906,9 +908,26 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   rc = ndctl_dimm_secure_erase_key(dimm);
-   if (rc < 0)
-   return rc;
+   /*
+* Setting crypto erase to be default. The other method will be
+* overwrite.
+*/
+   if (!param.crypto_erase && !param.overwrite) {
+   param.crypto_erase = true;
+   printf("No santize method passed in, default to 
crypto-erase\n");
+   }
+
+   if (param.crypto_erase) {
+   rc = ndctl_dimm_secure_erase_key(dimm);
+   if (rc < 0)
+   return rc;
+   }
+
+   if (param.overwrite) {
+   rc = ndctl_dimm_overwrite_key(dimm);
+   if (rc < 0)
+   return rc;
+   }
 
return 0;
 }
@@ -1006,6 +1025,12 @@ OPT_STRING('V', "label-version", , 
"version-number", \
 OPT_STRING('k', "key-handle", , "key-handle", \
"master encryption key handle")
 
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('c', "crypto-erase", _erase, \
+   "crypto erase a dimm"), \
+OPT_BOOLEAN('o', "overwrite", , \
+   "overwrite a dimm")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1038,6 +1063,11 @@ static const struct option init_options[] = {
 static const struct option key_options[] = {
BASE_OPTIONS(),
KEY_OPTIONS(),
+};
+
+static const struct option sanitize_options[] = {
+   BASE_OPTIONS(),
+   SANITIZE_OPTIONS(),
OPT_END(),
 };
 
@@ -1315,10 +1345,14 @@ int cmd_freeze_security(int argc, const char **argv, 
void *c

[PATCH v10 05/12] ndctl: add support for sanitize dimm

2019-01-24 Thread Dave Jiang
Add support to secure erase to libndctl and also command line option
of "sanitize-dimm" for ndctl. This will initiate the request to crypto
erase a DIMM.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 +
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   34 +++
 ndctl/builtin.h |1 
 ndctl/dimm.c|   29 +
 ndctl/lib/dimm.c|8 
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|1 
 ndctl/ndctl.c   |1 
 ndctl/util/keys.c   |   61 +--
 ndctl/util/keys.h   |6 +++
 10 files changed, 139 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 0327726b..fa4a1263 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -51,7 +51,8 @@ man1_MANS = \
ndctl-setup-passphrase.1 \
ndctl-update-passphrase.1 \
ndctl-remove-passphrase.1 \
-   ndctl-freeze-security.1
+   ndctl-freeze-security.1 \
+   ndctl-sanitize-dimm.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
new file mode 100644
index ..633498ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-sanitize-dimm(1)
+==
+
+NAME
+
+ndctl-sanitize-dimm - Perform a cryptographic destruction of the contents of 
the given NVDIMM(s).
+
+SYNOPSIS
+
+[verse]
+'ndctl sanitize-dimm'  [..] []
+
+DESCRIPTION
+---
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. The sanitize
+operation scrambles the data and info-blocks, but it does not touch
+the namespace labels. The user should expect namespaces to revert to raw mode
+after the region is next enabled following the operation. Security is disabled
+for the dimm after operation and ndctl will remove the key from the key ring
+and delete the associated key blob file.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+https://trustedcomputinggroup.org/wp-content/uploads/TCG_SWG_SIIS_Version_1_07_Revision_1_00.pdf
 [Trusted Computing Group Storage Interface Interactions Specification]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 0f567b9b..a474ec1a 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -36,4 +36,5 @@ int cmd_passphrase_setup(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 7105c539..e7872f52 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -895,6 +895,24 @@ static int action_security_freeze(struct ndctl_dimm *dimm,
return rc;
 }
 
+static int action_sanitize_dimm(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_secure_erase_key(dimm);
+   if (rc < 0)
+   return rc;
+
+   return 0;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1293,3 +1311,14 @@ int cmd_freeze_security(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_sanitize_dimm(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_sanitize_dimm,
+   base_options,
+   "ndctl sanitize-dimm  [..] 
[]");
+
+   fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 0a7eaaef..50650738 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -669,3 +669,11 @@ NDCTL_EXPORT int ndctl_dimm_freeze_security(struct 
ndctl_dimm *dimm)
 {
return write_security(dimm, "freeze");
 }
+
+

[PATCH v10 11/12] ndctl: add master secure erase support

2019-01-24 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 +
 ndctl/dimm.c|   13 ++-
 ndctl/lib/dimm.c|9 
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|1 +
 ndctl/util/keys.c   |   31 ++-
 ndctl/util/keys.h   |6 +++--
 7 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index b0b1ae21..78e1eb37 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -37,6 +37,12 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index c5c4a6cb..d4e2090f 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -911,6 +911,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -921,7 +927,8 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm);
+   rc = ndctl_dimm_secure_erase_key(dimm, param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1050,7 +1057,9 @@ OPT_STRING('k', "key-handle", , "key-handle", \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 #define MASTER_OPTIONS() \
 OPT_BOOLEAN('m', "master-passphrase", _pass, \
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 5c65d171..0a4ca797 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -772,3 +772,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index c9e530ba..014da63a 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -398,4 +398,5 @@ global:
ndctl_dimm_overwrite;
ndctl_dimm_wait_overwrite;
ndctl_dimm_update_master_passphrase;
+   ndctl_dimm_master_secure_erase;
 } LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 893e92e4..d220aa3d 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -707,6 +707,7 @@ int ndctl_dimm_overwrite(struct ndctl_dimm *dimm, long key);
 int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm);
 int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
long ckey, long nkey);
+int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm, long key);
 
 #define ND_KEY_DESC_SIZE   128
 #define ND_KEY_CMD_SIZE128
diff --git a/ndctl/util/keys.c b/ndctl/util/keys.c
index 44ad0391..85818c07 100644
--- a/ndctl/util/keys.c
+++ b/ndctl/util/keys.c
@@ -539,13 +539,14 @@ int ndctl_dimm_update_key(struct ndctl_dimm *dimm, const 
char *kek,
return 0;
 }
 
-static key_serial_t check_dimm_key(struct ndctl_dimm *dimm, bool need_key)
+static key_serial_t check_dimm_key(struct ndctl_dimm *dimm, bool need_key,
+   enum ndctl_key_type key_type)
 {
key_serial_t key;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
-   key = dimm_load_key(dimm, ND_USER_KEY);

[PATCH v10 07/12] ndctl: add modprobe conf file and load-keys ndctl command

2019-01-24 Thread Dave Jiang
Add load-keys command to ndctl. This will attempt to load the master key
and the related encrypted keys for nvdimms. Also add reference config file
for modprobe.d in order to call ndctl load-keys and inject keys associated
with the nvdimms into the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 
 Documentation/ndctl/ndctl-load-keys.txt |   45 +
 Makefile.am |4 
 contrib/nvdimm-security.conf|1 
 ndctl.spec.in   |1 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |1 
 ndctl/load-keys.c   |  256 +++
 ndctl/ndctl.c   |1 
 ndctl/util/keys.c   |   65 +---
 ndctl/util/keys.h   |7 +
 test/security.sh|2 
 12 files changed, 363 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-load-keys.txt
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/load-keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index fa4a1263..f64619b0 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -52,7 +52,8 @@ man1_MANS = \
ndctl-update-passphrase.1 \
ndctl-remove-passphrase.1 \
ndctl-freeze-security.1 \
-   ndctl-sanitize-dimm.1
+   ndctl-sanitize-dimm.1 \
+   ndctl-load-keys.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-load-keys.txt 
b/Documentation/ndctl/ndctl-load-keys.txt
new file mode 100644
index ..d0221c4c
--- /dev/null
+++ b/Documentation/ndctl/ndctl-load-keys.txt
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+
+include::attrs.adoc[]
+
+ndctl-load-keys(1)
+==
+
+NAME
+
+ndctl-load-keys - load encrypted keys with security passphrases for NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl load-keys' []
+
+DESCRIPTION
+---
+Provide a command to load the master key and the nvdimm encrypted keys for
+NVDIMM security operations. This command is expected to be called during
+initialization and before the libnvdimm kernel module is loaded. This works
+in conjunction with the provided module config file.
+
+NOTE: All nvdimm keys files are expected to be in format of:
+nvdimm__hostname
+The char '_' is used to deliminate the components in the file name. The char
+'_' can be used for any purpose starting with the hostname component and after.
+
+This command is typically never called directly by a user. It is only run via
+modprobe during early init.
+
+OPTIONS
+---
+-p::
+--key-path=::
+   Path to where key related files reside. This parameter is optional
+   and the default is set to {ndctl_keysdir}.
+
+-t::
+--tpm-handle=::
+   Provide the TPM handle (should be a string such as 0x8101) can
+   be optional if the key path contains a file called tpm.handle which
+   has the handle.
+
+include::../copyright.txt[]
diff --git a/Makefile.am b/Makefile.am
index e0c463a3..df8797ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,10 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+modprobe_file = contrib/nvdimm-security.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/nvdimm-security.conf b/contrib/nvdimm-security.conf
new file mode 100644
index ..e2bb7c0a
--- /dev/null
+++ b/contrib/nvdimm-security.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/bin/ndctl load-keys ; /sbin/modprobe --ignore-install 
libnvdimm $CMDLINE_OPTS
diff --git a/ndctl.spec.in b/ndctl.spec.in
index c075a0a0..0c8d6b40 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -120,6 +120,7 @@ make check
 %{bashcompdir}/
 %{_unitdir}/ndctl-monitor.service
 %{_sysconfdir}/ndctl/keys/
+%{_sysconfdir}/modprobe.d/nvdimm-security.conf
 
 %config(noreplace) %{_sysconfdir}/ndctl/monitor.conf
 
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 28b4e09b..cd3312ba 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -27,7 +27,8 @@ ndctl_SOURCES = ndctl.c \
monitor.c
 
 if ENABLE_KEYUTILS
-ndctl_SOURCES += util/keys.c
+ndctl_SOURCES += util/keys.c \
+   load-keys.c
 endif
 
 if ENABLE_DESTRUCTIVE
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index a474ec1a..733f41a5 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -37,4 +37,5 @@ int cmd_passphrase_update(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_load_keys(int argc, const char **argv

[PATCH v10 06/12] ndctl: add unit test for security ops (minus overwrite)

2019-01-24 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  222 ++
 2 files changed, 226 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..38b21183
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,222 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master-test"
+masterpath="$keypath/$masterkey"
+
+. ./common
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+}
+
+detect()
+{
+   dev="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].dev)"
+   [ -n "$dev" ] || err "$LINENO"
+   id="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].id)"
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   if [ ! -d "$keypath" ]; then
+   mkdir -p "$keypath"
+   fi
+
+   dd if=/dev/urandom bs=1 count=32 2>/dev/null | keyctl padd user 
"$masterkey" @u
+   keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
+}
+
+test_cleanup()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   fi
+
+   if [ -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob ]; then
+   rm -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob
+   fi
+
+   if [ -f $masterpath ]; then
+   rm -f "$masterpath"
+   fi
+
+   rm -f "$keypath"/"$NFIT_TEST_BUS0".kek
+}
+
+lock_dimm()
+{
+   $NDCTL disable-dimm "$dev"
+   # convert nmemX --> test_dimmY
+   # for now this is the only user of such a conversion so we can leave it
+   # inline once a subsequent user arrives we can refactor this to a
+   # helper in test/common:
+   #   get_test_dimm_path "nfit_test.0" "nmem3"
+   handle="$(ndctl list -b "$NFIT_TEST_BUS0"  -d "$dev" -i | jq -r 
.[].dimms[0].handle)"
+   test_dimm_path=""
+   for test_dimm in 
/sys/devices/platform/"$NFIT_TEST_BUS0"/nfit_test_dimm/test_dimm*; do
+   td_handle_file="$test_dimm/handle"
+   test -e "$td_handle_file" || continue
+   td_handle="$(cat "$td_handle_file")"
+   if [[ "$td_handle" -eq "$handle" ]]; then
+   test_dimm_path="$test_dimm"
+   break
+   fi
+   done
+   test -d "$test_dimm_path"
+
+   # now lock the dimm
+   echo 1 > "${test_dimm_path}/lock_dimm"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: locked"
+   err "$LINENO"
+   fi
+}
+
+get_security_state()
+{
+   $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq -r 
.[].dimms[0].security
+}
+
+setup_passphrase()
+{
+   $NDCTL setup-passphrase "$dev" -k user:"$masterkey"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err "$LINENO"
+   fi
+}
+
+remove_passphrase()
+{
+   $NDCTL remove-passphrase "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err "$LINENO"
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Inco

[PATCH v10 00/12] ndctl: add security support

2019-01-24 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v10:
- Remove install-encrypt-key support. setup-passphrase will take a master
  key handle in order to allow per NVDIMM master key. update-passphrase can
  take optional master key handle. (Dan)
- Rebased to latest ndctl. (Vishal)
- Moved the key management calls to ndctl/util and stop exporting. (Dan)

v9:
- Add install-encrypt-key command. (Dan)
- Change enable-passphrase to setup-passphrase. (Dan)
- Change disable-passphrase to remove-passphrase. (Dan)
- Change ndctl_dimm_get_security() to return state directly and remove
  ndctl_dimm_security_supported(). (Dan)
- Remove ND_SECURITY_UNSUPPORTED state
- change ND_SECURITY_* to NDCTL_SECURITY_*
- Fix man page issues (Dan, Jane)
- Define NDCTL_KEYSDIR in config.h (Dan)
- Break check_key_run_and_discard() to 3 helper functions. (Dan)
- Remove key path input parameter. (Dan)
- Remove master key input parameter. (Dan)
- Fixup various issues in security unit test script. (Vishal)

v8:
- Additional cleanup on test script. (Vishal)
- Change load-keys script into internal command for ndctl. (Dan)

v7:
- Added option to provide path to key directory. (Vishal)
- Cleaned up shell scripts. (Vishal)
- Cleaned up documentation. (Vishal)
- Addressed various comments from Vishal.

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (12):
  ndctl: add support for display security state
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: add modprobe conf file and load-keys ndctl command
  ndctl: add overwrite operation support
  ndctl: add wait-overwrite support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am |   10 
 Documentation/ndctl/intel-nvdimm-security.txt   |  141 +
 Documentation/ndctl/ndctl-freeze-security.txt   |   60 ++
 Documentation/ndctl/ndctl-list.txt  |8 
 Documentation/ndctl/ndctl-load-keys.txt |   45 ++
 Documentation/ndctl/ndctl-remove-passphrase.txt |   28 +
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   52 ++
 Documentation/ndctl/ndctl-setup-passphrase.txt  |   54 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   58 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt|   31 +
 Makefile.am |4 
 configure.ac|   17 +
 contrib/nvdimm-security.conf|1 
 ndctl.spec.in   |3 
 ndctl/Makefile.am   |6 
 ndctl/builtin.h |7 
 ndctl/dimm.c|  242 -
 ndctl/lib/Makefile.am   |4 
 ndctl/lib/dimm.c|  183 ++
 ndctl/lib/libndctl.sym  |9 
 ndctl/libndctl.h|   28 +
 ndctl/load-keys.c   |  256 +
 ndctl/ndctl.c   |7 
 ndctl/util/keys.c   |  650 +++
 ndctl/util/keys.h   |   60 ++
 test/Makefile.am|4 
 test/security.sh|  220 
 util/json.c |   17 +
 28 files changed, 2193 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 100644

[PATCH v10 02/12] ndctl: add passphrase update to ndctl

2019-01-24 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |5 
 Documentation/ndctl/ndctl-setup-passphrase.txt  |   47 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   51 +++
 configure.ac|   17 +
 ndctl.spec.in   |2 
 ndctl/Makefile.am   |5 
 ndctl/builtin.h |2 
 ndctl/dimm.c|   83 
 ndctl/lib/Makefile.am   |4 
 ndctl/lib/dimm.c|   24 +
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|9 
 ndctl/ndctl.c   |2 
 ndctl/util/keys.c   |  460 +++
 ndctl/util/keys.h   |   29 +
 15 files changed, 729 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-setup-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/util/keys.c
 create mode 100644 ndctl/util/keys.h

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7e17f206..79b12f8b 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,9 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-setup-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
@@ -56,6 +58,7 @@ attrs.adoc: $(srcdir)/Makefile.am
$(AM_V_GEN) cat <<- EOF >$@
:ndctl_monitorconfdir: $(ndctl_monitorconfdir)
:ndctl_monitorconf: $(ndctl_monitorconf)
+   :ndctl_keysdir: $(ndctl_keysdir)
EOF
 
 XML_DEPS = \
diff --git a/Documentation/ndctl/ndctl-setup-passphrase.txt 
b/Documentation/ndctl/ndctl-setup-passphrase.txt
new file mode 100644
index ..1594f110
--- /dev/null
+++ b/Documentation/ndctl/ndctl-setup-passphrase.txt
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+
+include::attrs.adoc[]
+
+ndctl-setup-passphrase(1)
+=
+
+NAME
+
+ndctl-setup-passphrase - setup and enable the security passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl setup-passphrase'  [..] -k  []
+
+DESCRIPTION
+---
+Enable the security passphrase for one or more NVDIMMs.
+
+Prerequisite for command to succeed:
+1. The master key has already been loaded into the user key ring.
+2. ndctl install-encrypt-key has been executed successfully.
+
+The encrypted key blobs will be created by ndctl in {ndctl_keysdir} directory
+with the file name of "nvdimm__.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in {ndctl_keysdir}.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-k::
+--key_handle=::
+   The encryption key (master) key handle, used for sealing the DIMM
+   encrypted keys. The format is :.
+   i.e. trusted:nvdimm-master
+   This key is expected to be loaded in the kernel's user keyring.
+
+-v::
+--verbose::
+Emit debug messages for the namespace check process.
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..05573968
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+
+include::attrs.adoc[]
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  [..] []
+
+DESCRIPTION
+---
+Update the security passphrase for one or more NVDIMMs.
+Prerequisite for command to succeed:
+1. The master key has already been loaded into the user key ring.
+2. ndctl install-encrypt-key has been executed successfully.
+3. setup-passphrase has successfully been executed previously on the NVDIMM
+   or NVDIMM has been successfully unlocked by the kernel.
+
+The updated key blobs will be created by ndctl in {ndctl_keysdir} directory
+with the file name of "nvdimm__.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-k::
+--key_handle=::
+   The new encryption key (master) key handle, used for sealing the DIMM
+   encrypted keys. The format is :.
+   i.e. trusted:nvdimm-master
+   This key is expected to be loaded in the kernel's user keyring.
+   This parameter is optional. If none provided, ndctl will determine
+   th

[PATCH v10 04/12] ndctl: add support for freeze security

2019-01-24 Thread Dave Jiang
Add support for freeze security to libndctl and also command line option
of "freeze-security" for ndctl. This will lock the ability to make changes
to the NVDIMM security.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 +
 Documentation/ndctl/ndctl-freeze-security.txt |   58 +
 ndctl/builtin.h   |1 
 ndctl/dimm.c  |   28 
 ndctl/lib/dimm.c  |5 ++
 ndctl/lib/libndctl.sym|1 
 ndctl/libndctl.h  |1 
 ndctl/ndctl.c |1 
 8 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 3b543216..0327726b 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -50,7 +50,8 @@ man1_MANS = \
ndctl-monitor.1 \
ndctl-setup-passphrase.1 \
ndctl-update-passphrase.1 \
-   ndctl-remove-passphrase.1
+   ndctl-remove-passphrase.1 \
+   ndctl-freeze-security.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-freeze-security.txt 
b/Documentation/ndctl/ndctl-freeze-security.txt
new file mode 100644
index ..d14b8a39
--- /dev/null
+++ b/Documentation/ndctl/ndctl-freeze-security.txt
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-freeze-security(1)
+
+
+NAME
+
+ndctl-freeze-security - Set the given DIMM(s) to reject future security 
operations
+
+SYNOPSIS
+
+[verse]
+'ndctl freeze-security'  [..] []
+
+DESCRIPTION
+---
+Prevent any further security operations on the given DIMMs until the
+next reboot. This is used in scenarios where the administrator has
+taken all expected security actions for the current boot and wants the
+DIMM to enforce / lock the current state.
+
+EXAMPLES
+
+
+[verse]
+ndctl list -d nmem0
+[
+  {
+"dev":"nmem0",
+"id":"cdab-0a-07e0-",
+"handle":0,
+"phys_id":0,
+"security":"unlocked"
+  }
+]
+
+[verse]
+ndctl freeze-security  nmem0
+security freezed 1 nmem.
+
+[verse]
+ndctl list -d nmem0
+[
+  {
+"dev":"nmem0",
+"id":"cdab-0a-07e0-",
+"handle":0,
+"phys_id":0,
+"security":"frozen"
+  }
+]
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 9deb175b..0f567b9b 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -35,4 +35,5 @@ int cmd_inject_smart(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 045f9408..7105c539 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -877,6 +877,24 @@ static int action_passphrase_remove(struct ndctl_dimm 
*dimm,
return ndctl_dimm_remove_key(dimm);
 }
 
+static int action_security_freeze(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_freeze_security(dimm);
+   if (rc < 0)
+   error("Failed to freeze security for %s\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1265,3 +1283,13 @@ int cmd_passphrase_remove(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_freeze_security(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_security_freeze, 
base_options,
+   "ndctl freeze-security  [..] 
[]");
+
+   fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index a944c9af..0a7eaaef 100644
--- a/ndctl/lib/dimm.c
+++ 

[PATCH v10 03/12] ndctl: add disable security support

2019-01-24 Thread Dave Jiang
Add support for disable security to libndctl and also command line option
of "disable-passphrase" for ndctl. This provides a way to disable security
on the nvdimm.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 ++-
 Documentation/ndctl/ndctl-remove-passphrase.txt |   26 ++
 ndctl/builtin.h |1 +
 ndctl/dimm.c|   23 
 ndctl/lib/dimm.c|9 
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|1 +
 ndctl/ndctl.c   |1 +
 ndctl/util/keys.c   |   27 +++
 ndctl/util/keys.h   |6 +
 10 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-remove-passphrase.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 79b12f8b..3b543216 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -49,7 +49,8 @@ man1_MANS = \
ndctl-list.1 \
ndctl-monitor.1 \
ndctl-setup-passphrase.1 \
-   ndctl-update-passphrase.1
+   ndctl-update-passphrase.1 \
+   ndctl-remove-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-remove-passphrase.txt 
b/Documentation/ndctl/ndctl-remove-passphrase.txt
new file mode 100644
index ..17ff905b
--- /dev/null
+++ b/Documentation/ndctl/ndctl-remove-passphrase.txt
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-remove-passphrase(1)
+===
+
+NAME
+
+ndctl-remove-passphrase - Stop a DIMM from locking at power-loss and requiring 
a passphrase to access media
+
+SYNOPSIS
+
+[verse]
+'ndctl remove-passphrase'  [..] []
+
+DESCRIPTION
+---
+Search the user key ring for the associated NVDIMM key. If not found,
+attempt to load the key blob. After disabling the passphrase successfully,
+remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 231fda25..9deb175b 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -34,4 +34,5 @@ int cmd_update_firmware(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 88319b31..045f9408 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -865,6 +865,18 @@ static int action_passphrase_update(struct ndctl_dimm 
*dimm,
return ndctl_dimm_update_key(dimm, param.kek);
 }
 
+static int action_passphrase_remove(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   return ndctl_dimm_remove_key(dimm);
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1242,3 +1254,14 @@ int cmd_passphrase_setup(int argc, const char **argv, 
struct ndctl_ctx *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_passphrase_remove(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_passphrase_remove,
+   base_options,
+   "ndctl remove-passphrase  [..] 
[]");
+
+   fprintf(stderr, "passphrase removed for %d nmem%s.\n", count >= 0 ? 
count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 72b6f66c..a944c9af 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -655,3 +655,12 @@ NDCTL_EXPORT int ndctl_dimm_update_passphrase(struct 
ndctl_dimm *dimm,
sprintf(buf, "update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_disable_passphrase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "disable %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 88557710..79b7f9e1 100644
--- a/ndctl/lib/libndctl.sym
+

[PATCH v10 01/12] ndctl: add support for display security state

2019-01-24 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   33 +
 ndctl/lib/libndctl.sym |1 +
 ndctl/libndctl.h   |   11 +++
 util/json.c|   17 +
 5 files changed, 70 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 11a7efe9..712223fc 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -598,3 +598,36 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT enum ndctl_security_state ndctl_dimm_get_security(
+   struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return NDCTL_SECURITY_INVALID;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return NDCTL_SECURITY_INVALID;
+
+   if (strcmp(buf, "disabled") == 0)
+   return NDCTL_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   return NDCTL_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   return NDCTL_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   return NDCTL_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   return NDCTL_SECURITY_OVERWRITE;
+
+   return NDCTL_SECURITY_INVALID;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 275db92e..0888c824 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -390,4 +390,5 @@ LIBNDCTL_19 {
 global:
ndctl_cmd_xlat_firmware_status;
ndctl_cmd_submit_xlat;
+   ndctl_dimm_get_security;
 } LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index e55a5932..e228c64f 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -684,6 +684,17 @@ int ndctl_dimm_fw_update_supported(struct ndctl_dimm 
*dimm);
 int ndctl_cmd_xlat_firmware_status(struct ndctl_cmd *cmd);
 int ndctl_cmd_submit_xlat(struct ndctl_cmd *cmd);
 
+enum ndctl_security_state {
+   NDCTL_SECURITY_INVALID = -1,
+   NDCTL_SECURITY_DISABLED = 0,
+   NDCTL_SECURITY_UNLOCKED,
+   NDCTL_SECURITY_LOCKED,
+   NDCTL_SECURITY_FROZEN,
+   NDCTL_SECURITY_OVERWRITE,
+};
+
+enum ndctl_security_state ndctl_dimm_get_security(struct ndctl_dimm *dimm);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..9dc420ce 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum ndctl_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,22 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   sstate = ndctl_dimm_get_security(dimm);
+   if (sstate == NDCTL_SECURITY_DISABLED)
+   jobj = json_object_new_string("disabled");
+   else if (sstate == NDCTL_SECURITY_UNLOCKED)
+   jobj = json_object_new_string("unlocked");
+   else if (sstate == NDCTL_SECURITY_LOCKED)
+   jobj = json_object_new_string("locked");
+   else if (sstate == NDCTL_SECURITY_FROZEN)
+   jobj = json_object_new_string("frozen");
+   else if (sstate == NDCTL_SECURITY_OVERWRITE)
+   jobj = json_object_new_string("overwrite");
+   else
+   jobj = NULL;
+   if (jobj)
+   json_object_object_add(jdimm, "security", jobj);
+
return jdimm;
  err:
json_object_put(jdimm);

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


Re: [PATCH] libnvdimm/security: Require nvdimm_security_setup_events() to succeed

2019-01-21 Thread Dave Jiang



On 1/19/2019 10:58 AM, Dan Williams wrote:

The following warning:

 ACPI0012:00: security event setup failed: -19

...is meant to capture exceptional failures of sysfs_get_dirent(),
however it will also fail in the common case when security support is
disabled. A few issues:

1/ A dev_warn() report for a common case is too chatty
2/ The setup of this notifier is generic, no need for it to be driven
from the nfit driver, it can exist completely in the core.
3/ If it fails for any reason besides security support being disabled,
that's fatal and should abort DIMM activation. Userspace may hang if
it never gets overwrite notifications.
4/ The dirent needs to be released.

Move the call to the core 'dimm' driver, make it conditional on security
support being active, make it fatal for the exceptional case, add the
missing sysfs_put() at device disable time.

Cc: Dave Jiang 
Signed-off-by: Dan Williams 


Reviewed-by: Dave Jiang 



---
  drivers/acpi/nfit/core.c   |5 -
  drivers/nvdimm/dimm.c  |6 ++
  drivers/nvdimm/dimm_devs.c |   22 +-
  drivers/nvdimm/nd.h|1 +
  include/linux/libnvdimm.h  |1 -
  5 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 9c95b82e5e5d..c38c914d8a58 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2073,11 +2073,6 @@ static int acpi_nfit_register_dimms(struct 
acpi_nfit_desc *acpi_desc)
if (!nvdimm)
continue;
  
-		rc = nvdimm_security_setup_events(nvdimm);

-   if (rc < 0)
-   dev_warn(acpi_desc->dev,
-   "security event setup failed: %d\n", rc);
-
nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
if (nfit_kernfs)
nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c
index 0cf58cabc9ed..3cf50274fadb 100644
--- a/drivers/nvdimm/dimm.c
+++ b/drivers/nvdimm/dimm.c
@@ -26,6 +26,12 @@ static int nvdimm_probe(struct device *dev)
struct nvdimm_drvdata *ndd;
int rc;
  
+	rc = nvdimm_security_setup_events(dev);

+   if (rc < 0) {
+   dev_err(dev, "security event setup failed: %d\n", rc);
+   return rc;
+   }
+
rc = nvdimm_check_config_data(dev);
if (rc) {
/* not required for non-aliased nvdimm, ex. NVDIMM-N */
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index 4890310df874..efe412a6b5b9 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -578,13 +578,25 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus 
*nvdimm_bus,
  }
  EXPORT_SYMBOL_GPL(__nvdimm_create);
  
-int nvdimm_security_setup_events(struct nvdimm *nvdimm)

+static void shutdown_security_notify(void *data)
  {
-   nvdimm->sec.overwrite_state = sysfs_get_dirent(nvdimm->dev.kobj.sd,
-   "security");
+   struct nvdimm *nvdimm = data;
+
+   sysfs_put(nvdimm->sec.overwrite_state);
+}
+
+int nvdimm_security_setup_events(struct device *dev)
+{
+   struct nvdimm *nvdimm = to_nvdimm(dev);
+
+   if (nvdimm->sec.state < 0 || !nvdimm->sec.ops
+   || !nvdimm->sec.ops->overwrite)
+   return 0;
+   nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, 
"security");
if (!nvdimm->sec.overwrite_state)
-   return -ENODEV;
-   return 0;
+   return -ENOMEM;
+
+   return devm_add_action_or_reset(dev, shutdown_security_notify, nvdimm);
  }
  EXPORT_SYMBOL_GPL(nvdimm_security_setup_events);
  
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h

index cfde992684e7..379bf4305e61 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -250,6 +250,7 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t 
phys,
  void nvdimm_set_aliasing(struct device *dev);
  void nvdimm_set_locked(struct device *dev);
  void nvdimm_clear_locked(struct device *dev);
+int nvdimm_security_setup_events(struct device *dev);
  #if IS_ENABLED(CONFIG_NVDIMM_KEYS)
  int nvdimm_security_unlock(struct device *dev);
  #else
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 7315977b64da..ad609617aeb8 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -235,7 +235,6 @@ static inline struct nvdimm *nvdimm_create(struct 
nvdimm_bus *nvdimm_bus,
cmd_mask, num_flush, flush_wpq, NULL, NULL);
  }
  
-int nvdimm_security_setup_events(struct nvdimm *nvdimm);

  const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd);
  const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd);
  u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,


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


Re: [PATCH v9 13/13] ndctl: documentation for security and key management

2019-01-18 Thread Dave Jiang



On 1/18/19 4:29 PM, Verma, Vishal L wrote:
> 
> On Thu, 2019-01-17 at 19:39 -0700, Dave Jiang wrote:
>> Add a "Theory of Operation" section describing the Intel DSM operations to
>> the relevant man pages.
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>  Documentation/ndctl/intel-nvdimm-security.txt   |  139 
>> +++
>>  Documentation/ndctl/ndctl-freeze-security.txt   |2 
>>  Documentation/ndctl/ndctl-remove-passphrase.txt |2 
>>  Documentation/ndctl/ndctl-sanitize-dimm.txt |2 
>>  Documentation/ndctl/ndctl-setup-passphrase.txt  |2 
>>  Documentation/ndctl/ndctl-update-passphrase.txt |2 
> 
> Should this also be also be added to the new command,
> install-kek/install-encryption-key?

Yep. Good catch!

> 
>>  6 files changed, 149 insertions(+)
>>  create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v9 02/13] ndctl: add command for ndctl to receive the key encryption key (master)

2019-01-18 Thread Dave Jiang



On 1/18/19 1:58 PM, Verma, Vishal L wrote:
> 
> On Thu, 2019-01-17 at 19:38 -0700, Dave Jiang wrote:
>> Add command that allows the user to provide the master encryption key name
>> to be installed in the key material directory where ndctl can refer to
>> for later security operations.
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>  Documentation/ndctl/Makefile.am   |3 
>>  Documentation/ndctl/ndctl-install-encrypt-key.txt |   31 +
>>  configure.ac  |3 
>>  ndctl/Makefile.am |4 -
>>  ndctl/builtin.h   |1 
>>  ndctl/kek.c   |  133 
>> +
>>  ndctl/lib/libndctl.c  |   31 +
>>  ndctl/lib/libndctl.sym|1 
>>  ndctl/lib/private.h   |1 
>>  ndctl/libndctl.h  |1 
>>  ndctl/ndctl.c |1 
>>  11 files changed, 208 insertions(+), 2 deletions(-)
>>  create mode 100644 Documentation/ndctl/ndctl-install-encrypt-key.txt
>>  create mode 100644 ndctl/kek.c
>>
>> diff --git a/Documentation/ndctl/Makefile.am 
>> b/Documentation/ndctl/Makefile.am
>> index a30b139b..7cb7bd6b 100644
>> --- a/Documentation/ndctl/Makefile.am
>> +++ b/Documentation/ndctl/Makefile.am
>> @@ -47,7 +47,8 @@ man1_MANS = \
>>  ndctl-inject-smart.1 \
>>  ndctl-update-firmware.1 \
>>  ndctl-list.1 \
>> -ndctl-monitor.1
>> +ndctl-monitor.1 \
>> +ndctl-install-encrypt-key.1
> 
> I think Dan's feedback was to call this command setup-passphrase?
> By 'install-encrypt-key' it seems unclear whether you mean "install
> encrypted key" vs. "install a key and encrypt it"
> Alternatively, the command can simply be 'install-kek', and the
> synopsis/description can expand on what 'kek' is and how it is used.

It probably should be called install encrypted key or install encryption
key. The next patch has setup-passphrase. This isn't it.

> 
>>  
>>  CLEANFILES = $(man1_MANS)
>>  
>> diff --git a/Documentation/ndctl/ndctl-install-encrypt-key.txt 
>> b/Documentation/ndctl/ndctl-install-encrypt-key.txt
>> new file mode 100644
>> index ..d00463e3
>> --- /dev/null
>> +++ b/Documentation/ndctl/ndctl-install-encrypt-key.txt
>> @@ -0,0 +1,31 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +ndctl-install-encrypt-key(1)
>> +
>> +
>> +NAME
>> +
>> +ndctl-install-encrypt-key - store encryption key name for nvdimm bus
> 
> "store the encryption key handle for an nvdimm bus"
> 
>> +
>> +SYNOPSIS
>> +
>> +[verse]
>> +'ndctl install-encrypt-key  [..] [-k > encryption key] []
>> +
>> +Take the provided master encryption key handle and store it in a file that
> 
> This sentence seems incomplete?
> 
>> +A file would be created for the designated bus provider.
>> +i.e. /etc/ndctl/keys/nfit_test.0.kek
> 
> With the makefile-vars-in-man-pages patch[1], all instances of hard
> coding this path in the documentation can now be converted to use the
> new scheme, and that should keep the man pages in sync with the actual
> build options.
> 
> [1]: https://patchwork.kernel.org/patch/10771507/
> 
> 
>> +The command only succeeds on bus(es) that contain nvdimms with security 
>> support.
> 
> This should be implied and is true for any command - the command will
> only work if the underlying feature is supported by the DIMM/platform,
> so I think we can omit this sentence.
> 
> I think you had a 'Description' section before, I think it is valuable
> to retain it and add a blurb about the keyctl steps that might be
> needed before invoking this command.
>> +
>> +OPTIONS
>> +---
>> +-k::
>> +--kek=::
>> +Key encryption key (master key) handle. The key handle has the format
>> +of :. i.e. trusted:nvdimm-master.
>> +
>> +-v::
>> +--verbose::
>> +Turn on debug output
>> +
>> +include::../copyright.txt[]
>>
>>
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [ndctl PATCH] ndctl, Documentation: Allow for Makefile variables in Documentation

2019-01-18 Thread Dave Jiang



On 1/18/19 1:43 PM, Vishal Verma wrote:
> We were starting to accumulate automake variables such as configureation
> file paths that were also referenced in Documentation man pages.
> However, until now, the man pages simply hard coded these paths to their
> default values. If a distribution were to configure such a path to
> something other than the default, the man pages would be out of sync
> with the reality.
> 
> Arrange for Makefile variables to be piped into an 'attrs.adoc' target
> (the variables to be piped in this manner still ahve to be listed
> explicitly). The different asciidoc(tor) source files can then include
> attrs.adoc to use these variables.
> 
> Finally, convert instances of '/etc/ndctl/monitor.conf' in the monitor
> documentation to use this new facility.
> 
> Cc: QI Fuli 
> Cc: Dave Jiang 
> Cc: Dan Williams 
> Signed-off-by: Vishal Verma 

Reviewed-by: Dave Jiang 

> ---
>  Documentation/ndctl/Makefile.am   | 10 +-
>  Documentation/ndctl/ndctl-monitor.txt | 16 ++--
>  2 files changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
> index a30b139..7e17f20 100644
> --- a/Documentation/ndctl/Makefile.am
> +++ b/Documentation/ndctl/Makefile.am
> @@ -51,6 +51,13 @@ man1_MANS = \
>  
>  CLEANFILES = $(man1_MANS)
>  
> +.ONESHELL:
> +attrs.adoc: $(srcdir)/Makefile.am
> + $(AM_V_GEN) cat <<- EOF >$@
> + :ndctl_monitorconfdir: $(ndctl_monitorconfdir)
> + :ndctl_monitorconf: $(ndctl_monitorconf)
> + EOF
> +
>  XML_DEPS = \
>   ../../version.m4 \
>   Makefile \
> @@ -63,7 +70,8 @@ XML_DEPS = \
>   xable-namespace-options.txt \
>   ars-description.txt \
>   labels-description.txt \
> - labels-options.txt
> + labels-options.txt \
> + attrs.adoc
>  
>  RM ?= rm -f
>  
> diff --git a/Documentation/ndctl/ndctl-monitor.txt 
> b/Documentation/ndctl/ndctl-monitor.txt
> index 363c398..2239f04 100644
> --- a/Documentation/ndctl/ndctl-monitor.txt
> +++ b/Documentation/ndctl/ndctl-monitor.txt
> @@ -1,5 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0
>  
> +include::attrs.adoc[]
> +
>  ndctl-monitor(1)
>  
>  
> @@ -19,11 +21,13 @@ objects and dumping the json format notifications to 
> syslog, standard
>  output or a logfile.
>  
>  The objects to monitor and smart events to notify can be selected by
> -setting options and/or the default configuration file
> -(/etc/ndctl/monitor.conf). Both of the values in configuration file
> -and in options will work. If there is a conflict, the values in
> -options will override the values in configuration file. The changed
> -values in configuration file will work after the monitor is restarted.
> +setting options and/or the configuration file at
> +{ndctl_monitorconfdir}/{ndctl_monitorconf}
> +
> +Both, the values in configuration file and in options will work. If
> +there is a conflict, the values in options will override the values in
> +the configuration file. Any updated values in the configuration file will
> +take effect only after the monitor process is restarted.
>  
>  EXAMPLES
>  
> @@ -83,7 +87,7 @@ will not work if "--daemon" is specified.
>  -c::
>  --config-file=::
>   Provide the config file to use. This overrides the default config
> - typically found in /etc/ndctl/
> + typically found in {ndctl_monitorconfdir}
>  
>  --daemon::
>   Run a monitor as a daemon.
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v9 00/13] ndctl: add security support

2019-01-18 Thread Dave Jiang



On 1/17/19 7:38 PM, Dave Jiang wrote:
> The following series implements mechanisms that utilize the sysfs knobs
> provided by the kernel in order to support the Intel DSM v1.8 spec
> that provides security to NVDIMM. The following abilities are added:
> 1. display security state
> 2. enable/update passphrase
> 3. disable passphrase
> 4. freeze security
> 5. secure erase
> 6. overwrite
> 7. master passphrase enable/update
> 
> v9:
> - Add install-encrypt-key command. (Dan)
> - Change enable-passphrase to setup-passphrase. (Dan)
> - Change disable-passphrase to remove-passphrase. (Dan)
> - Change ndctl_dimm_get_security() to return state directly and remove
>   ndctl_dimm_security_supported(). (Dan)
> - Remove ND_SECURITY_UNSUPPORTED state
> - change ND_SECURITY_* to NDCTL_SECURITY_*
> - Fix man page issues (Dan, Jane)
> - Define NDCTL_KEYSDIR in config.h (Dan)
> - Break check_key_run_and_discard() to 3 helper functions. (Dan)
> - Remove key path input parameter. (Dan)
> - Remove master key input parameter. (Dan)
> - Fixup various issues in security unit test script. (Vishal)

Left out one thing:
- Moved the load key script to an ndctl command load-keys. (Dan)

> 
> v8:
> - Additional cleanup on test script. (Vishal)
> - Change load-keys script into internal command for ndctl. (Dan)
> 
> v7:
> - Added option to provide path to key directory. (Vishal)
> - Cleaned up shell scripts. (Vishal)
> - Cleaned up documentation. (Vishal)
> - Addressed various comments from Vishal.
> 
> v6:
> - Fix spelling and grammar errors for documentation. (Jing)
> - Change bool for indicate master passphrase and old passphrase to enum.
> - Fix key load script master key name.
> - Update to match v15 of kernel patch series.
> 
> v5:
> - Updated to match latest kernel interface (encrypted keys)
> - Added overwrite support
> - Added support for DSM v1.8 master passphrase operations
> - Removed upcall related code
> - Moved security state to enum (Dan)
> - Change security output "security_state" to just "security". (Dan)
> - Break out enable and update passphrase operation. (Dan)
> - Security build can be compiled out when keyutils does not exist. (Dan)
> - Move all keyutils related operations to libndctl. (Dan)
> 
> v4:
> - Updated to match latest kernel interface.
> - Added unit test for all security calls
> 
> v3:
> - Added support to inject keys in order to update nvdimm security.
> 
> v2:
> - Fixup the upcall util to match recent kernel updates for nvdimm security.
> 
> ---
> 
> Dave Jiang (13):
>   ndctl: add support for display security state
>   ndctl: add command for ndctl to receive the key encryption key (master)
>   ndctl: add passphrase update to ndctl
>   ndctl: add disable security support
>   ndctl: add support for freeze security
>   ndctl: add support for sanitize dimm
>   ndctl: add unit test for security ops (minus overwrite)
>   ndctl: add modprobe conf file and load-keys ndctl command
>   ndctl: add overwrite operation support
>   ndctl: add wait-overwrite support
>   ndctl: master phassphrase management support
>   ndctl: add master secure erase support
>   ndctl: documentation for security and key management
> 
> 
>  Documentation/ndctl/Makefile.am   |   10 
>  Documentation/ndctl/intel-nvdimm-security.txt |  139 +
>  Documentation/ndctl/ndctl-freeze-security.txt |   60 ++
>  Documentation/ndctl/ndctl-install-encrypt-key.txt |   31 +
>  Documentation/ndctl/ndctl-list.txt|8 
>  Documentation/ndctl/ndctl-load-keys.txt   |   43 ++
>  Documentation/ndctl/ndctl-remove-passphrase.txt   |   28 +
>  Documentation/ndctl/ndctl-sanitize-dimm.txt   |   48 ++
>  Documentation/ndctl/ndctl-setup-passphrase.txt|   41 +
>  Documentation/ndctl/ndctl-update-passphrase.txt   |   43 ++
>  Documentation/ndctl/ndctl-wait-overwrite.txt  |   31 +
>  Makefile.am   |4 
>  configure.ac  |   17 +
>  contrib/nvdimm-security.conf  |1 
>  ndctl.spec.in |3 
>  ndctl/Makefile.am |5 
>  ndctl/builtin.h   |8 
>  ndctl/dimm.c  |  232 
>  ndctl/kek.c   |  133 +
>  ndctl/lib/Makefile.am |8 
>  ndctl/lib/dimm.c  |  183 +++
>  ndctl/lib/keys.c  |  581 
> +
>

[PATCH v9 08/13] ndctl: add modprobe conf file and load-keys ndctl command

2019-01-17 Thread Dave Jiang
Add load-keys command to ndctl. This will attempt to load the master key
and the related encrypted keys for nvdimms. Also add reference config file
for modprobe.d in order to call ndctl load-keys and inject keys associated
with the nvdimms into the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 
 Documentation/ndctl/ndctl-load-keys.txt |   43 +
 Makefile.am |4 
 contrib/nvdimm-security.conf|1 
 ndctl.spec.in   |1 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |1 
 ndctl/lib/keys.c|   64 +---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|2 
 ndctl/load-keys.c   |  257 +++
 ndctl/ndctl.c   |1 
 12 files changed, 357 insertions(+), 24 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-load-keys.txt
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/load-keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 2e535940..2481361f 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -53,7 +53,8 @@ man1_MANS = \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
-   ndctl-sanitize-dimm.1
+   ndctl-sanitize-dimm.1 \
+   ndctl-load-keys.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-load-keys.txt 
b/Documentation/ndctl/ndctl-load-keys.txt
new file mode 100644
index ..f153e9d7
--- /dev/null
+++ b/Documentation/ndctl/ndctl-load-keys.txt
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-load-keys(1)
+==
+
+NAME
+
+ndctl-load-keys - load encrypted keys with security passphrases for NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl load-keys' []
+
+DESCRIPTION
+---
+Provide a command to load the master key and the nvdimm encrypted keys for
+NVDIMM security operations. This command is expected to be called during
+initialization and before the libnvdimm kernel module is loaded. This works
+in conjunction with the provided module config file.
+
+NOTE: All nvdimm keys files are expected to be in format of:
+nvdimm__hostname
+The char '_' is used to deliminate the components in the file name. The char
+'_' can be used for any purpose starting with the hostname component and after.
+
+This command is typically never called directly by a user. It is only run via
+modprobe during early init.
+
+OPTIONS
+---
+-p::
+--key-path=::
+   Path to where key related files reside. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+-t::
+--tpm-handle=::
+   Provide the TPM handle (should be a string such as 0x8101) can
+   be optional if the key path contains a file called tpm.handle which
+   has the handle.
+
+include::../copyright.txt[]
diff --git a/Makefile.am b/Makefile.am
index e0c463a3..df8797ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,10 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+modprobe_file = contrib/nvdimm-security.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/nvdimm-security.conf b/contrib/nvdimm-security.conf
new file mode 100644
index ..e2bb7c0a
--- /dev/null
+++ b/contrib/nvdimm-security.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/bin/ndctl load-keys ; /sbin/modprobe --ignore-install 
libnvdimm $CMDLINE_OPTS
diff --git a/ndctl.spec.in b/ndctl.spec.in
index 3956d81d..0353c7e3 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -120,6 +120,7 @@ make check
 %{bashcompdir}/
 %{_unitdir}/ndctl-monitor.service
 %{_sysconfdir}/ndctl/keys/
+%{_sysconfdir}/modprobe.d/nvdimm-security.conf
 
 %config(noreplace) %{_sysconfdir}/ndctl/monitor.conf
 
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index e412dbf7..193dea74 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -25,7 +25,8 @@ ndctl_SOURCES = ndctl.c \
inject-error.c \
inject-smart.c \
monitor.c \
-   kek.c
+   kek.c \
+   load-keys.c
 
 if ENABLE_DESTRUCTIVE
 ndctl_SOURCES += ../test/blk_namespaces.c \
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 3d8f4ce7..416e4564 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -38,4 +38,5 @@ int cmd_passphrase_update(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
+int

[PATCH v9 05/13] ndctl: add support for freeze security

2019-01-17 Thread Dave Jiang
Add support for freeze security to libndctl and also command line option
of "freeze-security" for ndctl. This will lock the ability to make changes
to the NVDIMM security.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 +
 Documentation/ndctl/ndctl-freeze-security.txt |   58 +
 ndctl/builtin.h   |1 
 ndctl/dimm.c  |   28 
 ndctl/lib/dimm.c  |5 ++
 ndctl/lib/libndctl.sym|1 
 ndctl/libndctl.h  |1 
 ndctl/ndctl.c |1 
 8 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 96519653..f4230ead 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -51,7 +51,8 @@ man1_MANS = \
ndctl-install-encrypt-key.1 \
ndctl-setup-passphrase.1 \
ndctl-update-passphrase.1 \
-   ndctl-disable-passphrase.1
+   ndctl-disable-passphrase.1 \
+   ndctl-freeze-security.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-freeze-security.txt 
b/Documentation/ndctl/ndctl-freeze-security.txt
new file mode 100644
index ..d14b8a39
--- /dev/null
+++ b/Documentation/ndctl/ndctl-freeze-security.txt
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-freeze-security(1)
+
+
+NAME
+
+ndctl-freeze-security - Set the given DIMM(s) to reject future security 
operations
+
+SYNOPSIS
+
+[verse]
+'ndctl freeze-security'  [..] []
+
+DESCRIPTION
+---
+Prevent any further security operations on the given DIMMs until the
+next reboot. This is used in scenarios where the administrator has
+taken all expected security actions for the current boot and wants the
+DIMM to enforce / lock the current state.
+
+EXAMPLES
+
+
+[verse]
+ndctl list -d nmem0
+[
+  {
+"dev":"nmem0",
+"id":"cdab-0a-07e0-",
+"handle":0,
+"phys_id":0,
+"security":"unlocked"
+  }
+]
+
+[verse]
+ndctl freeze-security  nmem0
+security freezed 1 nmem.
+
+[verse]
+ndctl list -d nmem0
+[
+  {
+"dev":"nmem0",
+"id":"cdab-0a-07e0-",
+"handle":0,
+"phys_id":0,
+"security":"frozen"
+  }
+]
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 3d71cb30..8434766d 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -36,4 +36,5 @@ int cmd_install_kek(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index f71eafe7..3222def6 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -872,6 +872,24 @@ static int action_passphrase_remove(struct ndctl_dimm 
*dimm,
return ndctl_dimm_remove_key(dimm);
 }
 
+static int action_security_freeze(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_freeze_security(dimm);
+   if (rc < 0)
+   error("Failed to freeze security for %s\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1250,3 +1268,13 @@ int cmd_passphrase_remove(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_freeze_security(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_security_freeze, 
base_options,
+   "ndctl freeze-security  [..] 
[]");
+
+   fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index a944c9af..0a7eaaef 100644
--- a/ndctl/lib/dimm.

[PATCH v9 06/13] ndctl: add support for sanitize dimm

2019-01-17 Thread Dave Jiang
Add support to secure erase to libndctl and also command line option
of "sanitize-dimm" for ndctl. This will initiate the request to crypto
erase a DIMM.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 +
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   30 +
 ndctl/builtin.h |1 
 ndctl/dimm.c|   29 
 ndctl/lib/dimm.c|8 +++
 ndctl/lib/keys.c|   63 +--
 ndctl/lib/libndctl.sym  |2 +
 ndctl/libndctl.h|7 +++
 ndctl/ndctl.c   |1 
 9 files changed, 138 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index f4230ead..2e535940 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -52,7 +52,8 @@ man1_MANS = \
ndctl-setup-passphrase.1 \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
-   ndctl-freeze-security.1
+   ndctl-freeze-security.1 \
+   ndctl-sanitize-dimm.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
new file mode 100644
index ..f95be28f
--- /dev/null
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-sanitize-dimm(1)
+==
+
+NAME
+
+ndctl-sanitize-dimm - Perform a cryptographic destruction of the contents of 
the given NVDIMM(s).
+
+SYNOPSIS
+
+[verse]
+'ndctl sanitize-dimm'  [..] []
+
+DESCRIPTION
+---
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. After disabling
+the passphrase, remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+https://trustedcomputinggroup.org/wp-content/uploads/TCG_SWG_SIIS_Version_1_07_Revision_1_00.pdf
 [Trusted Computing Group Storage Interface Interactions Specification]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 8434766d..3d8f4ce7 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -37,4 +37,5 @@ int cmd_passphrase_setup(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 3222def6..c346b7fb 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -890,6 +890,24 @@ static int action_security_freeze(struct ndctl_dimm *dimm,
return rc;
 }
 
+static int action_sanitize_dimm(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_secure_erase_key(dimm);
+   if (rc < 0)
+   return rc;
+
+   return 0;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1278,3 +1296,14 @@ int cmd_freeze_security(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_sanitize_dimm(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_sanitize_dimm,
+   base_options,
+   "ndctl sanitize-dimm  [..] 
[]");
+
+   fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 0a7eaaef..50650738 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -669,3 +669,11 @@ NDCTL_EXPORT int ndctl_dimm_freeze_security(struct 
ndctl_dimm *dimm)
 {
return write_security(dimm, "freeze");
 }
+
+NDCTL_EXPORT int ndctl_dimm_secure_erase(struct ndctl_dimm *dimm, long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index fe618870..5353bdc4 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -38

[PATCH v9 13/13] ndctl: documentation for security and key management

2019-01-17 Thread Dave Jiang
Add a "Theory of Operation" section describing the Intel DSM operations to
the relevant man pages.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/intel-nvdimm-security.txt   |  139 +++
 Documentation/ndctl/ndctl-freeze-security.txt   |2 
 Documentation/ndctl/ndctl-remove-passphrase.txt |2 
 Documentation/ndctl/ndctl-sanitize-dimm.txt |2 
 Documentation/ndctl/ndctl-setup-passphrase.txt  |2 
 Documentation/ndctl/ndctl-update-passphrase.txt |2 
 6 files changed, 149 insertions(+)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt

diff --git a/Documentation/ndctl/intel-nvdimm-security.txt 
b/Documentation/ndctl/intel-nvdimm-security.txt
new file mode 100644
index ..f1de511d
--- /dev/null
+++ b/Documentation/ndctl/intel-nvdimm-security.txt
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+
+THEORY OF OPERATOIN
+---
+With the introduction of Intel Device Specific Methods (DSM) specification
+v1.7 and v1.8 [1], security DSMs were introduced. The operations supported by
+ndctl are enable passhprase, update passphrase, disable security,
+freeze security, secure (crypto) erase, overwrite, master passphrase enable,
+master passphrase update, and master passphrase secure (crypto) erase.
+The 'unlock' DSM is not supported by ndctl, that is left for the kernel to
+manage with some assistance from userspace.
+
+The security management for nvdimm is composed of two parts. The front end
+utilizes the Linux key management framework (trusted and encrypted keys [2]).
+It uses the keyutils on the user side and Linux key management APIs in
+the kernel. The backend takes the decrypted payload of the key and passes the
+plaintext payload to the nvdimm for processing.
+
+Unlike typical DSMs, the security DSMs are managed through the 'security'
+sysfs attribute under the dimm devices rather than an ioctl call by libndctl.
+The relevant key id is written to the 'security' attribute and the kernel will
+pull that key from the kernel's user key ring for processing.
+
+The entire security process starts with a master key that is used to seal the
+encrypted keys that are used to protect the passphrase for each nvdimm. We
+recommend using the *system* master key from the Trusted Platform
+Module (TPM), but a master key generated by the TPM can also
+be used. For testing purposes a user key with randomized payload can
+also be served as a master key. See [2] for details. To perform any security
+operations, it is expected that at the minimum the master key is already
+in the kernel's user keyring as shown in example below:
+
+> keyctl show
+Session Keyring
+ 736023423 --alswrv  0 0  keyring: _ses
+ 675104189 --alswrv  0 65534   \_ keyring: _uid.0
+ 680187394 --alswrv  0 0   \_ trusted: nvdimm-master
+
+Except for 'overwrite', all operations expect the relevant regions associated
+with the nvdimm are disabled before proceeding. For 'overwrite', in addition
+to the regions, the dimm itself is expected to be disabled.
+
+The following sections describe specifics of each security features.
+
+UNLOCK
+--
+Unlock is performed by the kernel, however a preparation step must happen
+before the unlock DSM can be issued by the kernel. The expectation is that
+during initramfs, a setup script is called before the libnvdimm module is
+loaded by modprobe. This script script will inject the master key and the
+related encrypted keys into the kernel's user key ring. A reference modprobe
+config file and a setup script have been provided by ndctl. During the 'probe'
+of the nvdimm driver, it will:
+1. First, check the security state of the device and see if the DIMM is locked
+2. Request the associated encrypted key from the kernel's user key ring.
+3. Finally, create the unlock DSM, copy the decrypted payload into the DSM
+   passphrase field, and issue the DSM to unlock the DIMM.
+
+If the DIMM is already unlocked, the kernel will attempt to revalidate the key.
+This can be overriden with a kernel module parameter. If we fail to revalidate
+the key, the kernel will freeze the security and disallow any further security
+configuration changes.
+
+SETUP USER PASSPHRASE
+--
+To setup the user passphrase for a DIMM, it is expected that the master key
+is already in the kernel's user key ring and the master key name is passed to
+ndctl so it can do key management. An encrypted key with a 32 bytes payload
+and encrypted key format 'enc32' is created and sealed by the master key. Be
+aware that the passphrase is never provided by or visible to the user.
+The decrypted payload for the encrypted key will be randomly generated by the
+kernel and userspace does not have access to this decrypted payload. When the
+encrypted key is created, a binary blob of the encrypted key is written to the
+key blob storage directory (/etc/ndctl/keys). The user is responsible for
+backing up the dimm key blobs to a secure l

[PATCH v9 09/13] ndctl: add overwrite operation support

2019-01-17 Thread Dave Jiang
Add support for overwrite to libndctl. The operation will be triggered
by the sanitize-dimm command with -o switch. This will initiate the request
to wipe the entire nvdimm. Success return of the command only indicate
overwrite has started and does not indicate completion of overwrite.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   12 ++-
 ndctl/dimm.c|   47 ---
 ndctl/lib/dimm.c|8 +
 ndctl/lib/keys.c|   33 ---
 ndctl/lib/libndctl.sym  |2 +
 ndctl/libndctl.h|7 
 6 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index f95be28f..158392bf 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -5,7 +5,7 @@ ndctl-sanitize-dimm(1)
 
 NAME
 
-ndctl-sanitize-dimm - Perform a cryptographic destruction of the contents of 
the given NVDIMM(s).
+ndctl-sanitize-dimm - Perform a cryptographic destruction or overwrite of the 
contents of the given NVDIMM(s).
 
 SYNOPSIS
 
@@ -23,6 +23,16 @@ OPTIONS
 ::
 include::xable-dimm-options.txt[]
 
+-c::
+--crypto-erase::
+   Replace the media encryption key causing all existing data to read as
+   cipher text with the new key.  This does not
+   change label data. This is the default sanitize method.
+
+-o::
+--ovewrite::
+   Wipe the entire DIMM, including label data. Can take significant time.
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index c346b7fb..2b259a4f 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -45,6 +45,8 @@ static struct parameters {
const char *outfile;
const char *infile;
const char *labelversion;
+   bool crypto_erase;
+   bool overwrite;
bool force;
bool json;
bool verbose;
@@ -901,9 +903,26 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   rc = ndctl_dimm_secure_erase_key(dimm);
-   if (rc < 0)
-   return rc;
+   /*
+* Setting crypto erase to be default. The other method will be
+* overwrite.
+*/
+   if (!param.crypto_erase && !param.overwrite) {
+   param.crypto_erase = true;
+   printf("No santize method passed in, default to 
crypto-erase\n");
+   }
+
+   if (param.crypto_erase) {
+   rc = ndctl_dimm_secure_erase_key(dimm);
+   if (rc < 0)
+   return rc;
+   }
+
+   if (param.overwrite) {
+   rc = ndctl_dimm_overwrite_key(dimm);
+   if (rc < 0)
+   return rc;
+   }
 
return 0;
 }
@@ -997,6 +1016,12 @@ OPT_BOOLEAN('f', "force", , \
 OPT_STRING('V', "label-version", , "version-number", \
"namespace label specification version (default: 1.1)")
 
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('c', "crypto-erase", _erase, \
+   "crypto erase a dimm"), \
+OPT_BOOLEAN('o', "overwrite", , \
+   "overwrite a dimm")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1026,6 +1051,12 @@ static const struct option init_options[] = {
OPT_END(),
 };
 
+static const struct option sanitize_options[] = {
+   BASE_OPTIONS(),
+   SANITIZE_OPTIONS(),
+   OPT_END(),
+};
+
 static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
int (*action)(struct ndctl_dimm *dimm, struct action_context 
*actx),
const struct option *options, const char *usage)
@@ -1300,10 +1331,14 @@ int cmd_freeze_security(int argc, const char **argv, 
void *ctx)
 int cmd_sanitize_dimm(int argc, const char **argv, void *ctx)
 {
int count = dimm_action(argc, argv, ctx, action_sanitize_dimm,
-   base_options,
+   sanitize_options,
"ndctl sanitize-dimm  [..] 
[]");
 
-   fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0,
-   count > 1 ? "s" : "");
+   if (param.overwrite)
+   fprintf(stderr, "overwrite issued for %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
+   else
+   fprintf(stderr, "sanitized %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
inde

[PATCH v9 03/13] ndctl: add passphrase update to ndctl

2019-01-17 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |4 
 Documentation/ndctl/ndctl-setup-passphrase.txt  |   34 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   36 ++
 configure.ac|   14 +
 ndctl.spec.in   |2 
 ndctl/builtin.h |2 
 ndctl/dimm.c|   68 +++-
 ndctl/lib/Makefile.am   |8 
 ndctl/lib/dimm.c|   24 +
 ndctl/lib/keys.c|  387 +++
 ndctl/lib/libndctl.sym  |3 
 ndctl/libndctl.h|   31 ++
 ndctl/ndctl.c   |2 
 13 files changed, 603 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-setup-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/lib/keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7cb7bd6b..7b155d4d 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -48,7 +48,9 @@ man1_MANS = \
ndctl-update-firmware.1 \
ndctl-list.1 \
ndctl-monitor.1 \
-   ndctl-install-encrypt-key.1
+   ndctl-install-encrypt-key.1 \
+   ndctl-setup-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-setup-passphrase.txt 
b/Documentation/ndctl/ndctl-setup-passphrase.txt
new file mode 100644
index ..7d8a1abb
--- /dev/null
+++ b/Documentation/ndctl/ndctl-setup-passphrase.txt
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-setup-passphrase(1)
+=
+
+NAME
+
+ndctl-setup-passphrase - setup and enable the security passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl setup-passphrase'  [..] []
+
+DESCRIPTION
+---
+Enable the security passphrase for one or more NVDIMMs.
+
+Prerequisite for command to succeed:
+1. The master key has already been loaded into the user key ring.
+2. ndctl install-encrypt-key has been executed successfully.
+
+The encrypted key blobs will be created by ndctl in /etc/ndctl/keys directory
+with the file name of "nvdimm__.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in /etc/nvdimm.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..ff49ae2d
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  [..] []
+
+DESCRIPTION
+---
+Update the security passphrase for one or more NVDIMMs.
+Prerequisite for command to succeed:
+1. The master key has already been loaded into the user key ring.
+2. ndctl install-encrypt-key has been executed successfully.
+3. setup-passphrase has successfully been executed previously on the NVDIMM
+   or NVDIMM has been successfully unlocked by the kernel.
+
+The updated key blobs will be created by ndctl in /etc/ndctl/keys directory
+with the file name of "nvdimm__.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
+
+SEE ALSO:
+-
+linkndctl:ndctl-setup-passphrase[1]
diff --git a/configure.ac b/configure.ac
index 61e91e0a..3c909cd0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,11 +154,25 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
+
 ndctl_monitorconfdir=${sysconfdir}/ndctl
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
 AC_SUBST([ndctl_monitorconf])
 
+AC_ARG_WITH([keyutils],
+   AS_HELP_STRING([--with-keyutils],
+   [Enable keyutils functionality (security).  
@<:@default=yes@:>@]), [], [with_keyutils=yes])
+
+if test "x$with_keyutils" = "xyes"; then
+   AC_CHECK_HEADERS([keyutils.h],,[
+   AC_MSG_ERROR([keyutils.h not found, consider installing
+ keyutils-libs-devel.])
+   ])
+fi
+AS_IF([test "x$with_keyutils" = "xyes"],
+   [AC_DEFINE([ENABLE_KEYUTILS], [1], [Enable keyutils support])])
+AM_CONDITIONAL([ENABLE_KEYUTILS], [test "x$with_keyutils" = 

[PATCH v9 11/13] ndctl: master phassphrase management support

2019-01-17 Thread Dave Jiang
Adding master passphrase enabling and update to ndctl. This is a new
feature from Intel DSM v1.8.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-setup-passphrase.txt  |5 +
 Documentation/ndctl/ndctl-update-passphrase.txt |5 +
 ndctl/dimm.c|   21 
 ndctl/lib/dimm.c|9 ++
 ndctl/lib/keys.c|  110 ++-
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|   16 +++
 7 files changed, 133 insertions(+), 34 deletions(-)

diff --git a/Documentation/ndctl/ndctl-setup-passphrase.txt 
b/Documentation/ndctl/ndctl-setup-passphrase.txt
index 7d8a1abb..044e9deb 100644
--- a/Documentation/ndctl/ndctl-setup-passphrase.txt
+++ b/Documentation/ndctl/ndctl-setup-passphrase.txt
@@ -31,4 +31,9 @@ OPTIONS
 ::
 include::xable-dimm-options.txt[]
 
+-m::
+--master-passphrase::
+   Indicates that we are managing the master passphrase instead of the
+   user passphrase.
+
 include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
index ff49ae2d..09e69832 100644
--- a/Documentation/ndctl/ndctl-update-passphrase.txt
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -29,6 +29,11 @@ OPTIONS
 ::
 include::xable-dimm-options.txt[]
 
+-m::
+--master-passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase.
+
 include::../copyright.txt[]
 
 SEE ALSO:
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index df0c187c..4a7cca8e 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,7 @@ static struct parameters {
const char *labelversion;
bool crypto_erase;
bool overwrite;
+   bool master_pass;
bool force;
bool json;
bool verbose;
@@ -847,7 +848,8 @@ static int action_key_enable(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_enable_key(dimm);
+   return ndctl_dimm_enable_key(dimm,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_key_update(struct ndctl_dimm *dimm,
@@ -859,7 +861,8 @@ static int action_key_update(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_update_key(dimm);
+   return ndctl_dimm_update_key(dimm,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_remove(struct ndctl_dimm *dimm,
@@ -1040,6 +1043,10 @@ OPT_BOOLEAN('c', "crypto-erase", _erase, \
 OPT_BOOLEAN('o', "overwrite", , \
"overwrite a dimm")
 
+#define MASTER_OPTIONS() \
+OPT_BOOLEAN('m', "master-passphrase", _pass, \
+   "use master passphrase")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1069,9 +1076,15 @@ static const struct option init_options[] = {
OPT_END(),
 };
 
+static const struct option master_options[] = {
+   BASE_OPTIONS(),
+   MASTER_OPTIONS(),
+};
+
 static const struct option sanitize_options[] = {
BASE_OPTIONS(),
SANITIZE_OPTIONS(),
+   MASTER_OPTIONS(),
OPT_END(),
 };
 
@@ -1306,7 +1319,7 @@ int cmd_update_firmware(int argc, const char **argv, 
struct ndctl_ctx *ctx)
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx)
 {
int count = dimm_action(argc, argv, ctx, action_key_update,
-   base_options,
+   master_options,
"ndctl update-passphrase  [..] 
[]");
 
fprintf(stderr, "passphrase updated for %d nmem%s.\n", count >= 0 ? 
count : 0,
@@ -1317,7 +1330,7 @@ int cmd_passphrase_update(int argc, const char **argv, 
struct ndctl_ctx *ctx)
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx)
 {
int count = dimm_action(argc, argv, ctx, action_key_enable,
-   base_options,
+   master_options,
"ndctl setup-passphrase  [..] 
[]");
 
fprintf(stderr, "passphrase enabled for %d nmem%s.\n", count >= 0 ? 
count : 0,
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 150e337a..5c65d171 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -763,3 +763,12 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
ndctl_dimm *dimm)
close(fd);
return rc;
 }
+
+NDCTL_EXPORT int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
+   long ckey, long nkey)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 50784284..9abff45b 100644
-

[PATCH v9 12/13] ndctl: add master secure erase support

2019-01-17 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 +
 ndctl/dimm.c|   13 ++-
 ndctl/lib/dimm.c|9 
 ndctl/lib/keys.c|   31 ++-
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|7 --
 6 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 158392bf..b01360d2 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -33,6 +33,12 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4a7cca8e..77dc6960 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -906,6 +906,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -916,7 +922,8 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm);
+   rc = ndctl_dimm_secure_erase_key(dimm, param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1041,7 +1048,9 @@ OPT_STRING('V', "label-version", , 
"version-number", \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 #define MASTER_OPTIONS() \
 OPT_BOOLEAN('m', "master-passphrase", _pass, \
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 5c65d171..0a4ca797 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -772,3 +772,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 9abff45b..4d89074d 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -466,14 +466,15 @@ NDCTL_EXPORT int ndctl_dimm_update_key(struct ndctl_dimm 
*dimm,
return 0;
 }
 
-static key_serial_t check_dimm_key(struct ndctl_dimm *dimm, bool need_key)
+static key_serial_t check_dimm_key(struct ndctl_dimm *dimm, bool need_key,
+   enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
key_serial_t key;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
-   key = dimm_load_key(dimm, ND_USER_KEY);
+   key = dimm_load_key(dimm, key_type);
if (key < 0 && need_key) {
err(ctx, "Unable to load key\n");
return -ENOKEY;
@@ -520,7 +521,7 @@ NDCTL_EXPORT int ndctl_dimm_remove_key(struct ndctl_dimm 
*dimm)
key_serial_t key;
int rc;
 
-   key = check_dimm_key(dimm, true);
+   key = check_dimm_key(dimm, true, ND_USER_KEY);
if (key < 0)
return key;
 
@@ -532,21 +533,31 @@ NDCTL_EXPORT int ndctl_dimm_remove_key(struct ndctl_dimm 
*dimm)
return discard_key(dimm);
 }
 
-NDCTL_EXPORT int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm)
+NDCTL_EXPORT int ndctl_dimm_secure_erase_key(struct ndctl_dimm *dimm,
+   enum ndctl_key_type key_type)
 {
key_serial_t key;
int rc;
 
-   ke

[PATCH v9 10/13] ndctl: add wait-overwrite support

2019-01-17 Thread Dave Jiang
Add a blocking 'wait-overwrite' command to ndctl to let a user wait for an
overwrite operation on a dimm to complete.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 ++
 ndctl/builtin.h  |1 
 ndctl/dimm.c |   27 +
 ndctl/lib/dimm.c |   78 ++
 ndctl/lib/libndctl.sym   |1 
 ndctl/libndctl.h |1 
 ndctl/ndctl.c|1 
 8 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 2481361f..77161cf5 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -54,7 +54,8 @@ man1_MANS = \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
ndctl-sanitize-dimm.1 \
-   ndctl-load-keys.1
+   ndctl-load-keys.1 \
+   ndctl-wait-overwrite.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-wait-overwrite.txt 
b/Documentation/ndctl/ndctl-wait-overwrite.txt
new file mode 100644
index ..5d4c72ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-wait-overwrite.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-wait-overwrite(1)
+===
+
+NAME
+
+ndctl-wait-overwrite - wait for nvdimm overwrite operation to complete
+
+SYNOPSIS
+
+[verse]
+'ndctl wait-overwrite'  []
+
+DESCRIPTION
+---
+The kernel provides a POLL(2) capable sysfs file ('security') to indicate
+the state of overwrite. The 'ndctl wait-overwrite' operation waits for
+a change in the state of the 'security' file across all specified dimms.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Emit debug messages for the overwrite wait process
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+linkndctl:ndctl-sanitize-dimm[1]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 416e4564..3e4fd14f 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -39,4 +39,5 @@ int cmd_passphrase_remove(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_wait_overwrite(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 2b259a4f..df0c187c 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -927,6 +927,24 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return 0;
 }
 
+static int action_wait_overwrite(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_wait_overwrite(dimm);
+   if (rc == 1)
+   printf("%s: overwrite completed.\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1342,3 +1360,12 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_overwrite(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_wait_overwrite,
+   base_options,
+   "ndctl wait-overwrite  [..] 
[]");
+
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index d7b70ebf..150e337a 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "private.h"
 
 static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
@@ -685,3 +686,80 @@ NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "overwrite %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   struct pollfd fds;
+   char buf[SYSFS_ATTR_SIZE];
+   int fd = 0, rc;
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(

[PATCH v9 07/13] ndctl: add unit test for security ops (minus overwrite)

2019-01-17 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  223 ++
 2 files changed, 227 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..4892ee0c
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,223 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master-test"
+masterpath="$keypath/$masterkey"
+
+. ./common
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+}
+
+detect()
+{
+   dev="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].dev)"
+   [ -n "$dev" ] || err "$LINENO"
+   id="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].id)"
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   if [ ! -d "$keypath" ]; then
+   mkdir -p "$keypath"
+   fi
+
+   dd if=/dev/urandom bs=1 count=32 2>/dev/null | keyctl padd user 
"$masterkey" @u
+   keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
+   $NDCTL install-encrypt-key "$NFIT_TEST_BUS0" -k user:"$masterkey"
+}
+
+test_cleanup()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   fi
+
+   if [ -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob ]; then
+   rm -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob
+   fi
+
+   if [ -f $masterpath ]; then
+   rm -f "$masterpath"
+   fi
+
+   rm -f "$keypath"/"$NFIT_TEST_BUS0".kek
+}
+
+lock_dimm()
+{
+   $NDCTL disable-dimm "$dev"
+   # convert nmemX --> test_dimmY
+   # for now this is the only user of such a conversion so we can leave it
+   # inline once a subsequent user arrives we can refactor this to a
+   # helper in test/common:
+   #   get_test_dimm_path "nfit_test.0" "nmem3"
+   handle="$(ndctl list -b "$NFIT_TEST_BUS0"  -d "$dev" -i | jq -r 
.[].dimms[0].handle)"
+   test_dimm_path=""
+   for test_dimm in 
/sys/devices/platform/"$NFIT_TEST_BUS0"/nfit_test_dimm/test_dimm*; do
+   td_handle_file="$test_dimm/handle"
+   test -e "$td_handle_file" || continue
+   td_handle="$(cat "$td_handle_file")"
+   if [[ "$td_handle" -eq "$handle" ]]; then
+   test_dimm_path="$test_dimm"
+   break
+   fi
+   done
+   test -d "$test_dimm_path"
+
+   # now lock the dimm
+   echo 1 > "${test_dimm_path}/lock_dimm"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: locked"
+   err "$LINENO"
+   fi
+}
+
+get_security_state()
+{
+   $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq -r 
.[].dimms[0].security
+}
+
+setup_passphrase()
+{
+   $NDCTL setup-passphrase "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err "$LINENO"
+   fi
+}
+
+remove_passphrase()
+{
+   $NDCTL remove-passphrase "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err "$LINENO"
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" !

[PATCH v9 00/13] ndctl: add security support

2019-01-17 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v9:
- Add install-encrypt-key command. (Dan)
- Change enable-passphrase to setup-passphrase. (Dan)
- Change disable-passphrase to remove-passphrase. (Dan)
- Change ndctl_dimm_get_security() to return state directly and remove
  ndctl_dimm_security_supported(). (Dan)
- Remove ND_SECURITY_UNSUPPORTED state
- change ND_SECURITY_* to NDCTL_SECURITY_*
- Fix man page issues (Dan, Jane)
- Define NDCTL_KEYSDIR in config.h (Dan)
- Break check_key_run_and_discard() to 3 helper functions. (Dan)
- Remove key path input parameter. (Dan)
- Remove master key input parameter. (Dan)
- Fixup various issues in security unit test script. (Vishal)

v8:
- Additional cleanup on test script. (Vishal)
- Change load-keys script into internal command for ndctl. (Dan)

v7:
- Added option to provide path to key directory. (Vishal)
- Cleaned up shell scripts. (Vishal)
- Cleaned up documentation. (Vishal)
- Addressed various comments from Vishal.

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (13):
  ndctl: add support for display security state
  ndctl: add command for ndctl to receive the key encryption key (master)
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: add modprobe conf file and load-keys ndctl command
  ndctl: add overwrite operation support
  ndctl: add wait-overwrite support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am   |   10 
 Documentation/ndctl/intel-nvdimm-security.txt |  139 +
 Documentation/ndctl/ndctl-freeze-security.txt |   60 ++
 Documentation/ndctl/ndctl-install-encrypt-key.txt |   31 +
 Documentation/ndctl/ndctl-list.txt|8 
 Documentation/ndctl/ndctl-load-keys.txt   |   43 ++
 Documentation/ndctl/ndctl-remove-passphrase.txt   |   28 +
 Documentation/ndctl/ndctl-sanitize-dimm.txt   |   48 ++
 Documentation/ndctl/ndctl-setup-passphrase.txt|   41 +
 Documentation/ndctl/ndctl-update-passphrase.txt   |   43 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt  |   31 +
 Makefile.am   |4 
 configure.ac  |   17 +
 contrib/nvdimm-security.conf  |1 
 ndctl.spec.in |3 
 ndctl/Makefile.am |5 
 ndctl/builtin.h   |8 
 ndctl/dimm.c  |  232 
 ndctl/kek.c   |  133 +
 ndctl/lib/Makefile.am |8 
 ndctl/lib/dimm.c  |  183 +++
 ndctl/lib/keys.c  |  581 +
 ndctl/lib/libndctl.c  |   31 +
 ndctl/lib/libndctl.sym|   16 +
 ndctl/lib/private.h   |1 
 ndctl/libndctl.h  |   79 +++
 ndctl/load-keys.c |  257 +
 ndctl/ndctl.c |8 
 test/Makefile.am  |4 
 test/security.sh  |  223 
 util/json.c   |   17 +
 31 files changed, 2280 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 

[PATCH v9 04/13] ndctl: add disable security support

2019-01-17 Thread Dave Jiang
Add support for disable security to libndctl and also command line option
of "disable-passphrase" for ndctl. This provides a way to disable security
on the nvdimm.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 ++
 Documentation/ndctl/ndctl-remove-passphrase.txt |   26 +
 ndctl/builtin.h |1 +
 ndctl/dimm.c|   23 ++
 ndctl/lib/dimm.c|9 +++
 ndctl/lib/keys.c|   29 +++
 ndctl/lib/libndctl.sym  |2 ++
 ndctl/libndctl.h|7 ++
 ndctl/ndctl.c   |1 +
 9 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-remove-passphrase.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7b155d4d..96519653 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -50,7 +50,8 @@ man1_MANS = \
ndctl-monitor.1 \
ndctl-install-encrypt-key.1 \
ndctl-setup-passphrase.1 \
-   ndctl-update-passphrase.1
+   ndctl-update-passphrase.1 \
+   ndctl-disable-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-remove-passphrase.txt 
b/Documentation/ndctl/ndctl-remove-passphrase.txt
new file mode 100644
index ..17ff905b
--- /dev/null
+++ b/Documentation/ndctl/ndctl-remove-passphrase.txt
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-remove-passphrase(1)
+===
+
+NAME
+
+ndctl-remove-passphrase - Stop a DIMM from locking at power-loss and requiring 
a passphrase to access media
+
+SYNOPSIS
+
+[verse]
+'ndctl remove-passphrase'  [..] []
+
+DESCRIPTION
+---
+Search the user key ring for the associated NVDIMM key. If not found,
+attempt to load the key blob. After disabling the passphrase successfully,
+remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 33c04983..3d71cb30 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -35,4 +35,5 @@ int cmd_inject_smart(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_install_kek(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_passphrase_remove(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index bea7cf62..f71eafe7 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -860,6 +860,18 @@ static int action_key_update(struct ndctl_dimm *dimm,
return ndctl_dimm_update_key(dimm);
 }
 
+static int action_passphrase_remove(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   if (ndctl_dimm_get_security(dimm) < 0) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   return ndctl_dimm_remove_key(dimm);
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1227,3 +1239,14 @@ int cmd_passphrase_setup(int argc, const char **argv, 
struct ndctl_ctx *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_passphrase_remove(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_passphrase_remove,
+   base_options,
+   "ndctl remove-passphrase  [..] 
[]");
+
+   fprintf(stderr, "passphrase removed for %d nmem%s.\n", count >= 0 ? 
count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 72b6f66c..a944c9af 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -655,3 +655,12 @@ NDCTL_EXPORT int ndctl_dimm_update_passphrase(struct 
ndctl_dimm *dimm,
sprintf(buf, "update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_disable_passphrase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "disable %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 1ae0ff02..fe618870 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -13,6 +13,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 

[PATCH v9 01/13] ndctl: add support for display security state

2019-01-17 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   33 +
 ndctl/lib/libndctl.sym |1 +
 ndctl/libndctl.h   |   11 +++
 util/json.c|   17 +
 5 files changed, 70 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 11a7efe9..712223fc 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -598,3 +598,36 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT enum ndctl_security_state ndctl_dimm_get_security(
+   struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return NDCTL_SECURITY_INVALID;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return NDCTL_SECURITY_INVALID;
+
+   if (strcmp(buf, "disabled") == 0)
+   return NDCTL_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   return NDCTL_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   return NDCTL_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   return NDCTL_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   return NDCTL_SECURITY_OVERWRITE;
+
+   return NDCTL_SECURITY_INVALID;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 275db92e..0888c824 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -390,4 +390,5 @@ LIBNDCTL_19 {
 global:
ndctl_cmd_xlat_firmware_status;
ndctl_cmd_submit_xlat;
+   ndctl_dimm_get_security;
 } LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index e55a5932..e228c64f 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -684,6 +684,17 @@ int ndctl_dimm_fw_update_supported(struct ndctl_dimm 
*dimm);
 int ndctl_cmd_xlat_firmware_status(struct ndctl_cmd *cmd);
 int ndctl_cmd_submit_xlat(struct ndctl_cmd *cmd);
 
+enum ndctl_security_state {
+   NDCTL_SECURITY_INVALID = -1,
+   NDCTL_SECURITY_DISABLED = 0,
+   NDCTL_SECURITY_UNLOCKED,
+   NDCTL_SECURITY_LOCKED,
+   NDCTL_SECURITY_FROZEN,
+   NDCTL_SECURITY_OVERWRITE,
+};
+
+enum ndctl_security_state ndctl_dimm_get_security(struct ndctl_dimm *dimm);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..9dc420ce 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum ndctl_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,22 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   sstate = ndctl_dimm_get_security(dimm);
+   if (sstate == NDCTL_SECURITY_DISABLED)
+   jobj = json_object_new_string("disabled");
+   else if (sstate == NDCTL_SECURITY_UNLOCKED)
+   jobj = json_object_new_string("unlocked");
+   else if (sstate == NDCTL_SECURITY_LOCKED)
+   jobj = json_object_new_string("locked");
+   else if (sstate == NDCTL_SECURITY_FROZEN)
+   jobj = json_object_new_string("frozen");
+   else if (sstate == NDCTL_SECURITY_OVERWRITE)
+   jobj = json_object_new_string("overwrite");
+   else
+   jobj = NULL;
+   if (jobj)
+   json_object_object_add(jdimm, "security", jobj);
+
return jdimm;
  err:
json_object_put(jdimm);

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


[PATCH v9 02/13] ndctl: add command for ndctl to receive the key encryption key (master)

2019-01-17 Thread Dave Jiang
Add command that allows the user to provide the master encryption key name
to be installed in the key material directory where ndctl can refer to
for later security operations.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 
 Documentation/ndctl/ndctl-install-encrypt-key.txt |   31 +
 configure.ac  |3 
 ndctl/Makefile.am |4 -
 ndctl/builtin.h   |1 
 ndctl/kek.c   |  133 +
 ndctl/lib/libndctl.c  |   31 +
 ndctl/lib/libndctl.sym|1 
 ndctl/lib/private.h   |1 
 ndctl/libndctl.h  |1 
 ndctl/ndctl.c |1 
 11 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-install-encrypt-key.txt
 create mode 100644 ndctl/kek.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a30b139b..7cb7bd6b 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,8 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-install-encrypt-key.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-install-encrypt-key.txt 
b/Documentation/ndctl/ndctl-install-encrypt-key.txt
new file mode 100644
index ..d00463e3
--- /dev/null
+++ b/Documentation/ndctl/ndctl-install-encrypt-key.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-install-encrypt-key(1)
+
+
+NAME
+
+ndctl-install-encrypt-key - store encryption key name for nvdimm bus
+
+SYNOPSIS
+
+[verse]
+'ndctl install-encrypt-key  [..] [-k ]
+
+Take the provided master encryption key handle and store it in a file that
+A file would be created for the designated bus provider.
+i.e. /etc/ndctl/keys/nfit_test.0.kek
+The command only succeeds on bus(es) that contain nvdimms with security 
support.
+
+OPTIONS
+---
+-k::
+--kek=::
+   Key encryption key (master key) handle. The key handle has the format
+   of :. i.e. trusted:nvdimm-master.
+
+-v::
+--verbose::
+   Turn on debug output
+
+include::../copyright.txt[]
diff --git a/configure.ac b/configure.ac
index a02a2d80..61e91e0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,9 @@ ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
 AC_SUBST([ndctl_monitorconf])
 
+ndctl_keysdir=${sysconfdir}/ndctl/keys
+AC_SUBST([ndctl_keysdir])
+
 my_CFLAGS="\
 -Wall \
 -Wchar-subscripts \
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 97de1814..e412dbf7 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -8,6 +8,7 @@ config.h: Makefile.am
$(AM_V_GEN) echo "/* Autogenerated by ndctl/Makefile.am */" >$@
$(AM_V_GEN) echo '#define NDCTL_CONF_FILE \
"$(ndctl_monitorconfdir)/$(ndctl_monitorconf)"' >>$@
+   $(AM_V_GEN) echo '#define NDCTL_KEYS_DIR  "$(ndctl_keysdir)"' >>$@
 
 ndctl_SOURCES = ndctl.c \
bus.c \
@@ -23,7 +24,8 @@ ndctl_SOURCES = ndctl.c \
util/json-firmware.c \
inject-error.c \
inject-smart.c \
-   monitor.c
+   monitor.c \
+   kek.c
 
 if ENABLE_DESTRUCTIVE
 ndctl_SOURCES += ../test/blk_namespaces.c \
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 17300df0..4af34f04 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -32,4 +32,5 @@ int cmd_bat(int argc, const char **argv, struct ndctl_ctx 
*ctx);
 #endif
 int cmd_update_firmware(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_install_kek(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/kek.c b/ndctl/kek.c
new file mode 100644
index ..1cb1555e
--- /dev/null
+++ b/ndctl/kek.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2019 Intel Corporation. All rights reserved. */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static struct parameters {
+   const char *kek;
+   bool verbose;
+} param;
+
+static int store_kek(const char *provider, const char *kek)
+{
+   char path[PATH_MAX];
+   FILE *fp;
+   ssize_t rc, wrote = 0;
+   int size = strlen(kek);
+
+   rc = sprintf(path, "%s/%s.kek", NDCTL_KEYS_DIR, provider);
+   if (rc < 0) {
+   perror("sprintf kek path failed");
+

Re: [PATCH v8 05/12] ndctl: add support for sanitize dimm

2019-01-17 Thread Dave Jiang


On 1/16/19 8:08 PM, Jane Chu wrote:
> Hi, Dave,
> 
> On 1/14/2019 12:07 PM, Dave Jiang wrote:
>> Add support to secure erase to libndctl and also command line option
>> of "sanitize-dimm" for ndctl. This will initiate the request to crypto
>> erase a DIMM.
>>
>> Signed-off-by: Dave Jiang 
>> ---
>>   Documentation/ndctl/Makefile.am |    3 +-
>>   Documentation/ndctl/ndctl-sanitize-dimm.txt |   38 
>>   ndctl/builtin.h |    1 +
>>   ndctl/dimm.c    |   52
>> +++
>>   ndctl/lib/dimm.c    |    8 
>>   ndctl/lib/keys.c    |   21 +--
>>   ndctl/lib/libndctl.sym  |    2 +
>>   ndctl/libndctl.h    |    9 +
>>   ndctl/ndctl.c   |    1 +
>>   9 files changed, 131 insertions(+), 4 deletions(-)
>>   create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt
>>
>> diff --git a/Documentation/ndctl/Makefile.am
>> b/Documentation/ndctl/Makefile.am
>> index a97f193d..bbea9674 100644
>> --- a/Documentation/ndctl/Makefile.am
>> +++ b/Documentation/ndctl/Makefile.am
>> @@ -51,7 +51,8 @@ man1_MANS = \
>>   ndctl-enable-passphrase.1 \
>>   ndctl-update-passphrase.1 \
>>   ndctl-disable-passphrase.1 \
>> -    ndctl-freeze-security.1
>> +    ndctl-freeze-security.1 \
>> +    ndctl-sanitize-dimm.1
>>     CLEANFILES = $(man1_MANS)
>>   diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt
>> b/Documentation/ndctl/ndctl-sanitize-dimm.txt
>> new file mode 100644
>> index ..79629964
>> --- /dev/null
>> +++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
>> @@ -0,0 +1,38 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +ndctl-sanitize-dimm(1)
>> +==
>> +
>> +NAME
>> +
>> +ndctl-sanitize-dimm - sanitize the data on the NVDIMM
>> +
>> +SYNOPSIS
>> +
>> +[verse]
>> +'ndctl sanitize'  []
> 
> Did you actually mean
>   'ndctl sanitize-dimm'  []
> ?

Yes. Thanks for the catch!

> 
> thanks!
> -jane
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: ndctl v64 stage tree -- Re: [PATCH v7 00/12] ndctl: add security support

2019-01-16 Thread Dave Jiang



On 1/16/19 11:02 AM, Jane Chu wrote:
> Hi, Vishal,
> 
> On 1/11/2019 3:36 PM, Verma, Vishal L wrote:
>> On Fri, 2019-01-11 at 15:18 -0800, Jane Chu wrote:
>>> Hi, Dave,
>>>
>>> Where is your ndctl git tree that might clone from to test the
>>> security features?
>> Hi Jane,
>>
>> I pushed out a for-v64-security branch with this (v7) series:
>>
>> https://github.com/pmem/ndctl/tree/for-v64-security
>>
>> I believe Dave plans to have v8 out early next week with a few changes,
>> most notably the loadkeys script becomes a first class ndctl command.
> 
> Just thought I might get a quick answer here although I haven't 
> gone thru all my homework.
> 
> I'm seeing "FAIL: security.sh" from "make KVER=5.0.0 check" on a NVDIMM 
> system,
> the security.sh.log indicates
> 
> + '[' '!' -f /usr/bin/keyctl ']'
> + '[' '!' -d /etc/ndctl/keys ']'
> + echo '/etc/ndctl/keys directory does not exist.'
> /etc/ndctl/keys directory does not exist.
> + exit 1
> 
> Indeed, what step did I miss?

Jane,
For now just go ahead and create the /etc/ndctl/keys directory to try
the test. Also, we discovered that the security test needs to be run as
a root user or sudo -i, just sudo will not do due to not having access
to the root user key ring. As Vishal said there's an update coming which
addresses several issues we found in the script.

> 
> Thanks!
> -jane
> 
>>  -Vishal
>>
>>> Thanks!
>>> -jane
>>>
>>> On 1/9/2019 9:53 AM, Dave Jiang wrote:
>>>> The following series implements mechanisms that utilize the sysfs
>>>> knobs
>>>> provided by the kernel in order to support the Intel DSM v1.8 spec
>>>> that provides security to NVDIMM. The following abilities are
>>>> added:
>>>> 1. display security state
>>>> 2. enable/update passphrase
>>>> 3. disable passphrase
>>>> 4. freeze security
>>>> 5. secure erase
>>>> 6. overwrite
>>>> 7. master passphrase enable/update
>>>>
>>> ___
>>> Linux-nvdimm mailing list
>>> Linux-nvdimm@lists.01.org
>>> https://lists.01.org/mailman/listinfo/linux-nvdimm
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v8 02/12] ndctl: add passphrase update to ndctl

2019-01-16 Thread Dave Jiang



On 1/16/19 10:43 AM, Verma, Vishal L wrote:
> 
> On Tue, 2019-01-15 at 17:56 -0800, Dan Williams wrote:
>> Some comments below...
>>
>> On Mon, Jan 14, 2019 at 12:06 PM Dave Jiang  wrote:
>>>
>>> Add API call for triggering sysfs knob to update the security for a DIMM
>>> in libndctl. Also add the ndctl "update-passphrase" to trigger the
>>> operation.
>>>
>>> Signed-off-by: Dave Jiang 
>>> ---
>>>  Documentation/ndctl/Makefile.am |4
>>>  Documentation/ndctl/ndctl-enable-passphrase.txt |   42 ++
>>>  Documentation/ndctl/ndctl-update-passphrase.txt |   38 ++
>>>  configure.ac|   19 +
>>>  ndctl.spec.in   |2
>>>  ndctl/Makefile.am   |3
>>>  ndctl/builtin.h |2
>>>  ndctl/dimm.c|   94 +-
>>>  ndctl/lib/Makefile.am   |8
>>>  ndctl/lib/dimm.c|   39 ++
>>>  ndctl/lib/keys.c|  390 
>>> +++
>>>  ndctl/lib/libndctl.sym  |4
>>>  ndctl/libndctl.h|   35 ++
>>>  ndctl/ndctl.c   |2
>>>  14 files changed, 669 insertions(+), 13 deletions(-)
>>>  create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
>>>  create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
>>>  create mode 100644 ndctl/lib/keys.c
>>>
>>> diff --git a/Documentation/ndctl/Makefile.am 
>>> b/Documentation/ndctl/Makefile.am
>>> index a30b139b..7adb 100644
>>> --- a/Documentation/ndctl/Makefile.am
>>> +++ b/Documentation/ndctl/Makefile.am
>>> @@ -47,7 +47,9 @@ man1_MANS = \
>>> ndctl-inject-smart.1 \
>>> ndctl-update-firmware.1 \
>>> ndctl-list.1 \
>>> -   ndctl-monitor.1
>>> +   ndctl-monitor.1 \
>>> +   ndctl-enable-passphrase.1 \
>>> +   ndctl-update-passphrase.1
>>>
>>>  CLEANFILES = $(man1_MANS)
>>>
>>> diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
>>> b/Documentation/ndctl/ndctl-enable-passphrase.txt
>>> new file mode 100644
>>> index ..c14a206c
>>> --- /dev/null
>>> +++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
>>> @@ -0,0 +1,42 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +
>>> +ndctl-enable-passphrase(1)
>>> +==
>>> +
>>> +NAME
>>> +
>>> +ndctl-enable-passphrase - enable the security passphrase for a NVDIMM
>>
>> *an NVDIMM
>>
>>> +
>>> +SYNOPSIS
>>> +
>>> +[verse]
>>> +'ndctl enable-passphrase'  []
>>
>> Is this true, there are no other required options besides the nmem
>> device? No support for more than one nmem at a time?
>>
>>> +
>>> +DESCRIPTION
>>> +---
>>> +Provide a command to enable the security passphrase for the NVDIMM.
>>
>> No need to say "Provide a command" that's assumed for a man page named
>> after a binary.
>>
>> So I'd say "Enable the security passphrase for one or more NVDIMMs.
>>
>>> +It is expected that the master key has already been loaded into the user
>>
>> Without listing the key-id as a required parameter it's not clear what
>> the usage should be.
>>
>>> +key ring. The encrypted key blobs will be created in /etc/nvdimm directory
>>
>> Is this stale, should be /etc/ndctl/keys, right? Given the directory
>> is changeable by the build system this source file should be built
>> with the key directory as a variable.
>>
>>> +with the file name of "nvdimm--.blob".
>>
>> That's quite a bit to type out? Is there a command to discover this
>> file name, or can we provide a short-hand?
> 
> I also noticed the actual file created was of the format:
> 
>   "nvdimm--.blob"
> 
> One of them should be made consistent with the other..

I'll fix the documentation. I changed the format for ease of parsing
sometimes during the development and missed the update to the
documentation here.

> 
>>
>>> +
>>> +The command will fail if the nvdimm key is already in the user key ring 
>>> and/or
>>> +the 

Re: [PATCH v15 07/16] acpi/nfit, libnvdimm: Add unlock of nvdimm support for Intel DIMMs

2019-01-15 Thread Dave Jiang



On 1/15/19 2:56 PM, Elliott, Robert (Persistent Memory) wrote:
> 
> 
>> -Original Message-
>> From: Linux-nvdimm [mailto:linux-nvdimm-boun...@lists.01.org] On Behalf Of 
>> Dave Jiang
>> Sent: Thursday, December 13, 2018 5:49 PM
>> To: dan.j.willi...@intel.com
>> Cc: linux-nvdimm@lists.01.org
>> Subject: [PATCH v15 07/16] acpi/nfit, libnvdimm: Add unlock of nvdimm 
>> support for Intel DIMMs
>>
>> From: Dan Williams 
>>
> ...
>> +static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
>> +{
>> +struct device *dev = >dev;
>> +struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
>> +struct key *key = NULL;
>> +int rc;
>> +
>> +/* The bus lock should be held at the top level of the call stack */
>> +lockdep_assert_held(_bus->reconfig_mutex);
>> +
>> +if (!nvdimm->sec.ops || !nvdimm->sec.ops->unlock
>> +|| nvdimm->sec.state < 0)
>> +return -EIO;
>> +
>> +/*
>> + * If the pre-OS has unlocked the DIMM, attempt to send the key
>> + * from request_key() to the hardware for verification.  Failure
>> + * to revalidate the key against the hardware results in a
>> + * freeze of the security configuration. I.e. if the OS does not
>> + * have the key, security is being managed pre-OS.
>> + */
>> +if (nvdimm->sec.state == NVDIMM_SECURITY_UNLOCKED) {
>> +if (!key_revalidate)
>> +return 0;
>> +
>> +key = nvdimm_key_revalidate(nvdimm);
>> +if (!key)
>> +return nvdimm_security_freeze(nvdimm);
> 
> If it's already unlocked, regardless of whether nvdimm_key_revalidate()
> succeeds or fails, I'm not sure you should call nvdimm_security_freeze().
> 
> The kernel doesn't know the key, so a hands-off policy seems prudent -
> don't send any commands that change the security state.  Some other
> software (pre-OS or application) must be handling the feature, and
> sending freeze lock might interfere with that software.

The intention is that if we don't have the key or the key verification
fails, we want to prevent any additional interaction with security for
this particular boot session. At least for the Intel implementation, a
reboot will clear the freeze.

> 
> Maybe you intended that to be "if (key)", intending to freeze if the
> kernel does have the correct key (so no application can change it and
> render the kernel out of sync)?
> 
> 
>> +} else
>> +key = nvdimm_request_key(nvdimm);
>> +
>> +if (!key)
>> +return -ENOKEY;
>> +
>> +rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key));
>> +dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key),
>> +rc == 0 ? "success" : "fail");
>> +
>> +nvdimm_put_key(key);
>> +nvdimm->sec.state = nvdimm_security_state(nvdimm);
>> +return rc;
>> +}
>> +
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH] libnvdimm/security: fix nvdimm_security_state() state request selection

2019-01-15 Thread Dave Jiang
The input parameter should be enum nvdimm_passphrase_type instead of bool
for selection of master/user for selection of extended master passphrase
state or the regular user passphrase state.

Fixes: 89fa9d8ea7bdf ("acpi/nfit, libnvdimm/security: add Intel DSM 1.8 master 
passphrase support")

Signed-off-by: Dave Jiang 
---
 drivers/nvdimm/nd-core.h |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index 2b2cf4e554d3..e5ffd5733540 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -54,12 +54,12 @@ struct nvdimm {
 };
 
 static inline enum nvdimm_security_state nvdimm_security_state(
-   struct nvdimm *nvdimm, bool master)
+   struct nvdimm *nvdimm, enum nvdimm_passphrase_type ptype)
 {
if (!nvdimm->sec.ops)
return -ENXIO;
 
-   return nvdimm->sec.ops->state(nvdimm, master);
+   return nvdimm->sec.ops->state(nvdimm, ptype);
 }
 int nvdimm_security_freeze(struct nvdimm *nvdimm);
 #if IS_ENABLED(CONFIG_NVDIMM_KEYS)

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


[PATCH] nfit_test: fix security state pull for nvdimm security nfit_test

2019-01-14 Thread Dave Jiang
The override status function needs to be updated to use the proper
request parameter in order to get the security state.

Fixes: 3c13e2ac74 ("tools/testing/nvdimm: Add test support for Intel nvdimm
security DSMs")

Reported-by: Vishal Verma 
Signed-off-by: Dave Jiang 
---
 tools/testing/nvdimm/dimm_devs.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/nvdimm/dimm_devs.c b/tools/testing/nvdimm/dimm_devs.c
index e75238404555..2d4baf57822f 100644
--- a/tools/testing/nvdimm/dimm_devs.c
+++ b/tools/testing/nvdimm/dimm_devs.c
@@ -18,8 +18,8 @@ ssize_t security_show(struct device *dev,
 * For the test version we need to poll the "hardware" in order
 * to get the updated status for unlock testing.
 */
-   nvdimm->sec.state = nvdimm_security_state(nvdimm, false);
-   nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, true);
+   nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
+   nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
 
switch (nvdimm->sec.state) {
case NVDIMM_SECURITY_DISABLED:

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


[PATCH v8 08/12] ndctl: add overwrite operation support

2019-01-14 Thread Dave Jiang
Add support for overwrite to libndctl. The operation will be triggered
by the sanitize-dimm command with -o switch. This will initiate the request
to wipe the entire nvdimm. Success return of the command only indicate
overwrite has started and does not indicate completion of overwrite.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |4 
 ndctl/dimm.c|   21 +
 ndctl/lib/dimm.c|8 
 ndctl/lib/keys.c|   21 -
 ndctl/lib/libndctl.sym  |2 ++
 ndctl/libndctl.h|8 
 6 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 79629964..a1a43bdd 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -35,4 +35,8 @@ include::xable-dimm-options.txt[]
Replaces encryption keys and securely erases the data. This does not
change label data. This is the default sanitize method.
 
+-o::
+--ovewrite::
+   Wipe the entire DIMM, including label data. Can take significant time.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index a91b40d5..799823d6 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -48,6 +48,7 @@ static struct parameters {
const char *key_path;
const char *master_key;
bool crypto_erase;
+   bool overwrite;
bool force;
bool json;
bool verbose;
@@ -910,7 +911,7 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
 * Setting crypto erase to be default. The other method will be
 * overwrite.
 */
-   if (!param.crypto_erase) {
+   if (!param.crypto_erase && !param.overwrite) {
param.crypto_erase = true;
printf("No santize method passed in, default to 
crypto-erase\n");
}
@@ -921,6 +922,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return rc;
}
 
+   if (param.overwrite) {
+   rc = ndctl_dimm_overwrite_key(dimm, param.key_path);
+   if (rc < 0)
+   return rc;
+   }
+
return 0;
 }
 
@@ -1023,7 +1030,9 @@ OPT_STRING('m', "master-key", _key, 
":", \
 
 #define SANITIZE_OPTIONS() \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
-   "crypto erase a dimm")
+   "crypto erase a dimm"), \
+OPT_BOOLEAN('o', "overwrite", , \
+   "overwrite a dimm")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
@@ -1361,7 +1370,11 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
sanitize_options,
"ndctl sanitize-dimm  [..] 
[]");
 
-   fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0,
-   count > 1 ? "s" : "");
+   if (param.overwrite)
+   fprintf(stderr, "overwrite issued for %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
+   else
+   fprintf(stderr, "sanitized %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 285e09ce..f27b966c 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -685,3 +685,11 @@ NDCTL_EXPORT int ndctl_dimm_secure_erase(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "erase %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm *dimm, long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "overwrite %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 39c4143c..beb5ab3b 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -92,6 +92,7 @@ NDCTL_EXPORT char *ndctl_load_key_blob(struct ndctl_ctx *ctx,
err(ctx, "stat: %s\n", strerror(errno));
return NULL;
}
+
if ((st.st_mode & S_IFMT) != S_IFREG) {
err(ctx, "%s not a regular file\n", path);
return NULL;
@@ -418,10 +419,11 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
key = dimm_check_key(dimm, false);
if (key < 0) {
key = dimm_load_key(dimm, false, keypath);
-   if (key < 0) {
+   if (key < 0 && run_op != ndctl_dimm_overwrite) {
e

[PATCH v8 12/12] ndctl: documentation for security and key management

2019-01-14 Thread Dave Jiang
Add a "Theory of Operation" section describing the Intel DSM operations to
the relevant man pages.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |2 
 Documentation/ndctl/ndctl-enable-passphrase.txt  |2 
 Documentation/ndctl/ndctl-freeze-security.txt|2 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |2 
 Documentation/ndctl/ndctl-update-passphrase.txt  |2 
 6 files changed, 150 insertions(+)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt

diff --git a/Documentation/ndctl/intel-nvdimm-security.txt 
b/Documentation/ndctl/intel-nvdimm-security.txt
new file mode 100644
index ..13ef34d0
--- /dev/null
+++ b/Documentation/ndctl/intel-nvdimm-security.txt
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+
+THEORY OF OPERATOIN
+---
+With the introduction of Intel Device Specific Methods (DSM) specification
+v1.7 and v1.8 [1], security DSMs were introduced. The operations supported by
+ndctl are enable passhprase, update passphrase, disable security,
+freeze security, secure (crypto) erase, overwrite, master passphrase enable,
+master passphrase update, and master passphrase secure (crypto) erase.
+The 'unlock' DSM is not supported by ndctl, that is left for the kernel to
+manage with some assistance from userspace.
+
+The security management for nvdimm is composed of two parts. The front end
+utilizes the Linux key management framework (trusted and encrypted keys [2]).
+It uses the keyutils on the user side and Linux key management APIs in
+the kernel. The backend takes the decrypted payload of the key and passes the
+plaintext payload to the nvdimm for processing.
+
+Unlike typical DSMs, the security DSMs are managed through the 'security'
+sysfs attribute under the dimm devices rather than an ioctl call by libndctl.
+The relevant key id is written to the 'security' attribute and the kernel will
+pull that key from the kernel's user key ring for processing.
+
+The entire security process starts with a master key that is used to seal the
+encrypted keys that are used to protect the passphrase for each nvdimm. We
+recommend using the *system* master key from the Trusted Platform
+Module (TPM), but a master key generated by the TPM can also
+be used. For testing purposes a user key with randomized payload can
+also be served as a master key. See [2] for details. To perform any security
+operations, it is expected that at the minimum the master key is already
+in the kernel's user keyring as shown in example below:
+
+> keyctl show
+Session Keyring
+ 736023423 --alswrv  0 0  keyring: _ses
+ 675104189 --alswrv  0 65534   \_ keyring: _uid.0
+ 680187394 --alswrv  0 0   \_ trusted: nvdimm-master
+
+Except for 'overwrite', all operations expect the relevant regions associated
+with the nvdimm are disabled before proceeding. For 'overwrite', in addition
+to the regions, the dimm itself is expected to be disabled.
+
+The following sections describe specifics of each security features.
+
+UNLOCK
+--
+Unlock is performed by the kernel, however a preparation step must happen
+before the unlock DSM can be issued by the kernel. The expectation is that
+during initramfs, a setup script is called before the libnvdimm module is
+loaded by modprobe. This script script will inject the master key and the
+related encrypted keys into the kernel's user key ring. A reference modprobe
+config file and a setup script have been provided by ndctl. During the 'probe'
+of the nvdimm driver, it will:
+1. First, check the security state of the device and see if the DIMM is locked
+2. Request the associated encrypted key from the kernel's user key ring.
+3. Finally, create the unlock DSM, copy the decrypted payload into the DSM
+   passphrase field, and issue the DSM to unlock the DIMM.
+
+If the DIMM is already unlocked, the kernel will attempt to revalidate the key.
+This can be overriden with a kernel module parameter. If we fail to revalidate
+the key, the kernel will freeze the security and disallow any further security
+configuration changes.
+
+ENABLE USER PASSPHRASE
+--
+To enable the user passphrase for a DIMM, it is expected that the master key
+is already in the kernel's user key ring and the master key name is passed to
+ndctl so it can do key management. An encrypted key with a 32 bytes payload
+and encrypted key format 'enc32' is created and sealed by the master key. Be
+aware that the passphrase is never provided by or visible to the user.
+The decrypted payload for the encrypted key will be randomly generated by the
+kernel and userspace does not have access to this decrypted payload. When the
+encrypted key is created, a binary blob of the encrypted key is written to the
+designated key blob storage directory (/etc/ndctl/keys as default). The user is
+responsible for backing up the d

[PATCH v8 11/12] ndctl: add master secure erase support

2019-01-14 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 ++
 ndctl/dimm.c|   14 --
 ndctl/lib/dimm.c|9 +
 ndctl/lib/keys.c|   28 +++
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|5 +++--
 6 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index a1a43bdd..3a09ae59 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -39,4 +39,10 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4875e414..7f2d4873 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -908,6 +908,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -918,7 +924,9 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path,
+   param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1053,7 +1061,9 @@ OPT_BOOLEAN('M', "master-passphrase", _pass, 
\
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index dc945296..b9bf9cc2 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -780,3 +780,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 09ceeb57..c10dc436 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -463,13 +463,13 @@ NDCTL_EXPORT int ndctl_dimm_update_key(struct ndctl_dimm 
*dimm,
 
 static int check_key_run_and_discard(struct ndctl_dimm *dimm,
int (*run_op)(struct ndctl_dimm *, long), const char *name,
-   const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
key_serial_t key;
int rc;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
key = dimm_load_key(dimm, keypath, ND_USER_KEY);
if (key < 0 && run_op != ndctl_dimm_overwrite) {
@@ -486,8 +486,12 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
return rc;
}
 
+   /* we do not delete the key if master secure erase */
+   if (key_type == ND_MASTER_KEY)
+   return 0;
+
if (key) {
-   rc = dimm_remove_key(dimm, keypath, ND_USER_KEY);
+   rc = dimm_remove_key(dimm, keypath, key_type);
if (rc < 0)
err(ctx, "Unable to cleanup key.\n");
}
@@ -498,19 +502,27 @@ NDCTL_EXPORT int ndctl_dimm_disable_key(struct ndctl_dimm 
*dimm,
const char *keypath)
 {
return check_key_run_and_discard(dimm, ndctl_dimm_disable_passphrase,

[PATCH v8 09/12] ndctl: add wait-overwrite support

2019-01-14 Thread Dave Jiang
Add a blocking 'wait-overwrite' command to ndctl to let a user wait for an
overwrite operation on a dimm to complete.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 ++
 ndctl/builtin.h  |1 
 ndctl/dimm.c |   27 +
 ndctl/lib/dimm.c |   78 ++
 ndctl/lib/libndctl.sym   |1 
 ndctl/libndctl.h |1 
 ndctl/ndctl.c|1 
 8 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 0224cccd..9c1c95b5 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -53,7 +53,8 @@ man1_MANS = \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
ndctl-sanitize-dimm.1 \
-   ndctl-load-keys.1
+   ndctl-load-keys.1 \
+   ndctl-wait-overwrite.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-wait-overwrite.txt 
b/Documentation/ndctl/ndctl-wait-overwrite.txt
new file mode 100644
index ..5d4c72ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-wait-overwrite.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-wait-overwrite(1)
+===
+
+NAME
+
+ndctl-wait-overwrite - wait for nvdimm overwrite operation to complete
+
+SYNOPSIS
+
+[verse]
+'ndctl wait-overwrite'  []
+
+DESCRIPTION
+---
+The kernel provides a POLL(2) capable sysfs file ('security') to indicate
+the state of overwrite. The 'ndctl wait-overwrite' operation waits for
+a change in the state of the 'security' file across all specified dimms.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Emit debug messages for the overwrite wait process
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+linkndctl:ndctl-sanitize-dimm[1]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 2cdc0590..ebc3f5c7 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -38,4 +38,5 @@ int cmd_disable_passphrase(int argc, const char **argv, 
struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_wait_overwrite(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 799823d6..ce477981 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -931,6 +931,24 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return 0;
 }
 
+static int action_wait_overwrite(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_wait_overwrite(dimm);
+   if (rc == 1)
+   printf("%s: overwrite completed.\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1378,3 +1396,12 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_overwrite(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_wait_overwrite,
+   base_options,
+   "ndctl wait-overwrite  [..] 
[]");
+
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index f27b966c..eb950331 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "private.h"
 
 static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
@@ -693,3 +694,80 @@ NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "overwrite %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   struct pollfd fds;
+   char buf[SYSFS_ATTR_SIZE];
+   int fd = 0, rc;
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len)

[PATCH v8 00/12] ndctl: add security support

2019-01-14 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v8:
- Additional cleanup on test script. (Vishal)
- Change load-keys script into internal command for ndctl. (Dan)

v7:
- Added option to provide path to key directory. (Vishal)
- Cleaned up shell scripts. (Vishal)
- Cleaned up documentation. (Vishal)
- Addressed various comments from Vishal.

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (12):
  ndctl: add support for display security state
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: add modprobe conf file and load-keys ndctl command
  ndctl: add overwrite operation support
  ndctl: add wait-overwrite support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am  |9 
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |   35 +
 Documentation/ndctl/ndctl-enable-passphrase.txt  |   49 ++
 Documentation/ndctl/ndctl-freeze-security.txt|   22 +
 Documentation/ndctl/ndctl-list.txt   |8 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |   50 ++
 Documentation/ndctl/ndctl-update-passphrase.txt  |   45 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 +
 Makefile.am  |4 
 configure.ac |   19 +
 contrib/nvdimm-security.conf |1 
 ndctl.spec.in|3 
 ndctl/Makefile.am|6 
 ndctl/builtin.h  |7 
 ndctl/dimm.c |  259 ++-
 ndctl/lib/Makefile.am|8 
 ndctl/lib/dimm.c |  202 
 ndctl/lib/keys.c |  528 ++
 ndctl/lib/libndctl.sym   |   20 +
 ndctl/libndctl.h |   84 
 ndctl/load-keys.c|  260 +++
 ndctl/ndctl.c|7 
 test/Makefile.am |4 
 test/security.sh |  197 
 util/json.c  |   31 +
 26 files changed, 2015 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/lib/keys.c
 create mode 100644 ndctl/load-keys.c
 create mode 100755 test/security.sh

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


[PATCH v8 03/12] ndctl: add disable security support

2019-01-14 Thread Dave Jiang
Add support for disable security to libndctl and also command line option
of "disable-passphrase" for ndctl. This provides a way to disable security
on the nvdimm.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +-
 Documentation/ndctl/ndctl-disable-passphrase.txt |   33 +++
 ndctl/builtin.h  |1 +
 ndctl/dimm.c |   38 --
 ndctl/lib/dimm.c |9 +
 ndctl/lib/keys.c |   29 +
 ndctl/lib/libndctl.sym   |2 +
 ndctl/libndctl.h |8 +
 ndctl/ndctl.c|1 +
 9 files changed, 120 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7adb..31570a77 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -49,7 +49,8 @@ man1_MANS = \
ndctl-list.1 \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
-   ndctl-update-passphrase.1
+   ndctl-update-passphrase.1 \
+   ndctl-disable-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-disable-passphrase.txt 
b/Documentation/ndctl/ndctl-disable-passphrase.txt
new file mode 100644
index ..49f25898
--- /dev/null
+++ b/Documentation/ndctl/ndctl-disable-passphrase.txt
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-disable-passphrase(1)
+===
+
+NAME
+
+ndctl-disable-passphrase - disabling passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl disable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a generic interface for disabling passphrase for NVDIMM.
+
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. After disabling
+the passphrase, remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 231fda25..821ea690 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -34,4 +34,5 @@ int cmd_update_firmware(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 1ab6b29f..4f0466a1 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -864,6 +864,18 @@ static int action_key_update(struct ndctl_dimm *dimm,
param.key_path);
 }
 
+static int action_passphrase_disable(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   return ndctl_dimm_disable_key(dimm, param.key_path);
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -953,12 +965,14 @@ OPT_BOOLEAN('f', "force", , \
 OPT_STRING('V', "label-version", , "version-number", \
"namespace label specification version (default: 1.1)")
 
-#define KEY_OPTIONS() \
-OPT_STRING('m', "master-key", _key, ":", \
-   "master key for security"), \
+#define KEY_BASE_OPTIONS() \
 OPT_FILENAME('p', "key-path", _path, "key-path", \
"override the default key path")
 
+#define KEY_OPTIONS() \
+OPT_STRING('m', "master-key", _key, ":", \
+   "master key for security")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -988,8 +1002,15 @@ static const struct option init_options[] = {
OPT_END(),
 };
 
+static const struct option key_base_options[] = {
+   BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
+   OPT_END(),
+};
+
 static const struct option key_options[] = {
BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
KEY_OPTIONS(),
OPT_END(),
 };
@@ -1253,3 +1274,14 @@ int cmd_passphrase_setup(int argc, const char **argv, 
struct ndctl_ctx *ctx)
count > 1 ? "s" : "

[PATCH v8 10/12] ndctl: master phassphrase management support

2019-01-14 Thread Dave Jiang
Adding master passphrase enabling and update to ndctl. This is a new
feature from Intel DSM v1.8.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-enable-passphrase.txt |7 +
 Documentation/ndctl/ndctl-update-passphrase.txt |7 +
 ndctl/dimm.c|   13 +-
 ndctl/lib/dimm.c|9 ++
 ndctl/lib/keys.c|  127 ---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|   14 ++-
 7 files changed, 130 insertions(+), 48 deletions(-)

diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
index c14a206c..c025b1c3 100644
--- a/Documentation/ndctl/ndctl-enable-passphrase.txt
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -29,7 +29,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master=::
+--master-key=::
Key name for the master key used to seal the NVDIMM security keys.
The format would be :
i.e.: trusted:master-nvdimm
@@ -39,4 +39,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Indicates that we are managing the master passphrase instead of the
+   user passphrase.
+
 include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
index dd6e4e4e..8b5dfe01 100644
--- a/Documentation/ndctl/ndctl-update-passphrase.txt
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -26,7 +26,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master::
+--master-key=::
New key name for the master key to seal the new nvdimm key, or the
existing master key name. i.e trusted:master-key.
 
@@ -35,4 +35,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index ce477981..4875e414 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -49,6 +49,7 @@ static struct parameters {
const char *master_key;
bool crypto_erase;
bool overwrite;
+   bool master_pass;
bool force;
bool json;
bool verbose;
@@ -849,8 +850,8 @@ static int action_key_enable(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_enable_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_enable_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_key_update(struct ndctl_dimm *dimm,
@@ -862,8 +863,8 @@ static int action_key_update(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_update_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_update_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_disable(struct ndctl_dimm *dimm,
@@ -1044,7 +1045,9 @@ OPT_FILENAME('p', "key-path", _path, 
"key-path", \
 
 #define KEY_OPTIONS() \
 OPT_STRING('m', "master-key", _key, ":", \
-   "master key for security")
+   "master key for security"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 #define SANITIZE_OPTIONS() \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index eb950331..dc945296 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -771,3 +771,12 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
ndctl_dimm *dimm)
close(fd);
return rc;
 }
+
+NDCTL_EXPORT int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
+   long ckey, long nkey)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index beb5ab3b..09ceeb57 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -17,7 +17,7 @@
 #include "private.h"
 
 static int get_key_path(struct ndctl_dimm *dimm, char *path,
-   enum ndctl_key_type key_type, const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
char hostname[HOST_NAME_MAX];

[PATCH v8 05/12] ndctl: add support for sanitize dimm

2019-01-14 Thread Dave Jiang
Add support to secure erase to libndctl and also command line option
of "sanitize-dimm" for ndctl. This will initiate the request to crypto
erase a DIMM.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 +-
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   38 
 ndctl/builtin.h |1 +
 ndctl/dimm.c|   52 +++
 ndctl/lib/dimm.c|8 
 ndctl/lib/keys.c|   21 +--
 ndctl/lib/libndctl.sym  |2 +
 ndctl/libndctl.h|9 +
 ndctl/ndctl.c   |1 +
 9 files changed, 131 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a97f193d..bbea9674 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -51,7 +51,8 @@ man1_MANS = \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
-   ndctl-freeze-security.1
+   ndctl-freeze-security.1 \
+   ndctl-sanitize-dimm.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
new file mode 100644
index ..79629964
--- /dev/null
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-sanitize-dimm(1)
+==
+
+NAME
+
+ndctl-sanitize-dimm - sanitize the data on the NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl sanitize'  []
+
+DESCRIPTION
+---
+Provide a generic interface to crypto erase a NVDIMM.
+
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. After disabling
+the passphrase, remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+-c::
+--crypto-erase::
+   Replaces encryption keys and securely erases the data. This does not
+   change label data. This is the default sanitize method.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index f7469598..55bee47c 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -36,4 +36,5 @@ int cmd_passphrase_setup(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 19301791..a91b40d5 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,7 @@ static struct parameters {
const char *labelversion;
const char *key_path;
const char *master_key;
+   bool crypto_erase;
bool force;
bool json;
bool verbose;
@@ -894,6 +895,35 @@ static int action_security_freeze(struct ndctl_dimm *dimm,
return rc;
 }
 
+static int action_sanitize_dimm(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   /*
+* Setting crypto erase to be default. The other method will be
+* overwrite.
+*/
+   if (!param.crypto_erase) {
+   param.crypto_erase = true;
+   printf("No santize method passed in, default to 
crypto-erase\n");
+   }
+
+   if (param.crypto_erase) {
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -991,6 +1021,10 @@ OPT_FILENAME('p', "key-path", _path, 
"key-path", \
 OPT_STRING('m', "master-key", _key, ":", \
"master key for security")
 
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('c', "crypto-erase", _erase, \
+   "crypto erase a dimm")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1033,6 +1067,13 @@ static const struct option key_options[] = {
OPT_END(),
 }

[PATCH v8 02/12] ndctl: add passphrase update to ndctl

2019-01-14 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |4 
 Documentation/ndctl/ndctl-enable-passphrase.txt |   42 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   38 ++
 configure.ac|   19 +
 ndctl.spec.in   |2 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |2 
 ndctl/dimm.c|   94 +-
 ndctl/lib/Makefile.am   |8 
 ndctl/lib/dimm.c|   39 ++
 ndctl/lib/keys.c|  390 +++
 ndctl/lib/libndctl.sym  |4 
 ndctl/libndctl.h|   35 ++
 ndctl/ndctl.c   |2 
 14 files changed, 669 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/lib/keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a30b139b..7adb 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,9 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-enable-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
new file mode 100644
index ..c14a206c
--- /dev/null
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-enable-passphrase(1)
+==
+
+NAME
+
+ndctl-enable-passphrase - enable the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl enable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to enable the security passphrase for the NVDIMM.
+It is expected that the master key has already been loaded into the user
+key ring. The encrypted key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in /etc/nvdimm. Do not touch the /etc/nvdimm
+directory and let ndctl manage the keys, unless you know what you are doing.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master=::
+   Key name for the master key used to seal the NVDIMM security keys.
+   The format would be :
+   i.e.: trusted:master-nvdimm
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..dd6e4e4e
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to update the security key for NVDIMM.
+It is expected that the current and the new (if new master key is desired)
+master key has already been loaded into the user key ring. The new encrypted
+key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master::
+   New key name for the master key to seal the new nvdimm key, or the
+   existing master key name. i.e trusted:master-key.
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/configure.ac b/configure.ac
index aa07ec7b..22efc871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,6 +154,7 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
+
 ndctl_monitorconfdir=${sysconfdir}/ndctl
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
@@ -161,6 +162,24 @@ AC_SUBST([ndctl_monitorconf])
 AC_DEFINE_UNQUOTED(NDCTL_CONF_FILE, 
["$ndctl_monitorconfdir/$ndctl_monitorconf"],
[default ndctl monitor conf path])
 
+AC_ARG_WITH([keyutils],
+   AS_HELP_STRING([--with-keyutils],
+   

[PATCH v8 07/12] ndctl: add modprobe conf file and load-keys ndctl command

2019-01-14 Thread Dave Jiang
Add load-keys command to ndctl. This will attempt to load the master key
and the related encrypted keys for nvdimms. Also add reference config file
for modprobe.d in order to call ndctl load-keys and inject keys associated
with the nvdimms into the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 
 Makefile.am |4 +
 contrib/nvdimm-security.conf|1 
 ndctl.spec.in   |1 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |1 
 ndctl/lib/keys.c|   60 ++---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|2 
 ndctl/load-keys.c   |  260 +++
 ndctl/ndctl.c   |1 
 11 files changed, 314 insertions(+), 23 deletions(-)
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/load-keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index bbea9674..0224cccd 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -52,7 +52,8 @@ man1_MANS = \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
-   ndctl-sanitize-dimm.1
+   ndctl-sanitize-dimm.1 \
+   ndctl-load-keys.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Makefile.am b/Makefile.am
index e0c463a3..df8797ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,10 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+modprobe_file = contrib/nvdimm-security.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/nvdimm-security.conf b/contrib/nvdimm-security.conf
new file mode 100644
index ..e2bb7c0a
--- /dev/null
+++ b/contrib/nvdimm-security.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/bin/ndctl load-keys ; /sbin/modprobe --ignore-install 
libnvdimm $CMDLINE_OPTS
diff --git a/ndctl.spec.in b/ndctl.spec.in
index 66466db6..afed8a43 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -121,6 +121,7 @@ make check
 %{_sysconfdir}/ndctl/monitor.conf
 %{_unitdir}/ndctl-monitor.service
 %{_sysconfdir}/ndctl/keys/
+%{_sysconfdir}/modprobe.d/nvdimm-security.conf
 
 %files -n daxctl
 %defattr(-,root,root)
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 120941a4..eafae05d 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -16,7 +16,8 @@ ndctl_SOURCES = ndctl.c \
util/json-firmware.c \
inject-error.c \
inject-smart.c \
-   monitor.c
+   monitor.c \
+   load-keys.c
 
 if ENABLE_DESTRUCTIVE
 ndctl_SOURCES += ../test/blk_namespaces.c \
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 55bee47c..2cdc0590 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -37,4 +37,5 @@ int cmd_passphrase_update(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 42281394..39c4143c 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -71,16 +71,23 @@ static int get_key_desc(struct ndctl_dimm *dimm, char *desc,
return 0;
 }
 
-static char *load_key_blob(struct ndctl_ctx *ctx, const char *path, int *size)
+NDCTL_EXPORT char *ndctl_load_key_blob(struct ndctl_ctx *ctx,
+   const char *path, int *size, const char *postfix, int dirfd)
 {
struct stat st;
-   FILE *bfile = NULL;
-   ssize_t read;
-   int rc;
+   ssize_t read_bytes = 0;
+   int rc, fd;
char *blob, *pl;
char prefix[] = "load ";
 
-   rc = stat(path, );
+   fd = openat(dirfd, path, O_RDONLY);
+   if (fd < 0) {
+   err(ctx, "failed to open file %s: %s\n",
+   path, strerror(errno));
+   return NULL;
+   }
+
+   rc = fstat(fd, );
if (rc < 0) {
err(ctx, "stat: %s\n", strerror(errno));
return NULL;
@@ -96,31 +103,42 @@ static char *load_key_blob(struct ndctl_ctx *ctx, const 
char *path, int *size)
}
 
*size = st.st_size + sizeof(prefix) - 1;
+   /*
+* We need to increment postfix and space.
+* "keyhandle=" is 10 bytes, plus null termination.
+*/
+   if (postfix)
+   *size += strlen(postfix) + 10 + 1;
blob = malloc(*size);
if (!blob) {
err(ctx, "Unable to alloca

[PATCH v8 06/12] ndctl: add unit test for security ops (minus overwrite)

2019-01-14 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  197 ++
 2 files changed, 201 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..9f69b481
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,197 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+dev_no=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master-test"
+masterpath="$keypath/$masterkey"
+
+. ./common
+
+lockpath="/sys/devices/platform/${NFIT_TEST_BUS0}/nfit_test_dimm/test_dimm"
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+}
+
+detect()
+{
+   dev="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].dev)"
+   [ -n "$dev" ] || err "$LINENO"
+   id="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].id)"
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   keyctl add user "$masterkey" "$(dd if=/dev/urandom bs=1 count=32 
2>/dev/null)" @u
+   keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
+}
+
+test_cleanup()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   fi
+
+   if [ -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob ]; then
+   rm -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob
+   fi
+
+   if [ -f $masterpath ]; then
+   rm -f "$masterpath"
+   fi
+}
+
+lock_dimm()
+{
+   $NDCTL disable-dimm "$dev"
+   dev_no="${dev#nmem}"
+   echo 1 > "${lockpath}${dev_no}/lock_dimm"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+get_security_state()
+{
+   $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq -r 
.[].dimms[0].security
+}
+
+enable_passphrase()
+{
+   $NDCTL enable-passphrase -m user:"$masterkey" "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err $LINENO
+   fi
+}
+
+disable_passphrase()
+{
+   $NDCTL disable-passphrase "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+update_security()
+{
+   $NDCTL update-passphrase -m user:"$masterkey" "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err $LINENO
+   fi
+}
+
+freeze_security()
+{
+   $NDCTL freeze-security "$dev"
+}
+
+test_1_security_enable_and_disable()
+{
+   enable_passphrase
+   disable_passphrase
+}
+
+test_2_security_enable_and_update()
+{
+   enable_passphrase
+   update_security
+   disable_passphrase
+}
+
+test_3_security_enable_and_erase()
+{
+   enable_passphrase
+   erase_security
+}
+
+test_4_security_unlock()
+{
+   enable_passphrase
+   lock_dimm
+   $NDCTL enable-dimm "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo &qu

[PATCH v8 04/12] ndctl: add support for freeze security

2019-01-14 Thread Dave Jiang
Add support for freeze security to libndctl and also command line option
of "freeze-security" for ndctl. This will lock the ability to make changes
to the NVDIMM security.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 ++-
 Documentation/ndctl/ndctl-freeze-security.txt |   20 ++
 ndctl/builtin.h   |1 +
 ndctl/dimm.c  |   28 +
 ndctl/lib/dimm.c  |5 
 ndctl/lib/libndctl.sym|1 +
 ndctl/libndctl.h  |1 +
 ndctl/ndctl.c |1 +
 8 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 31570a77..a97f193d 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -50,7 +50,8 @@ man1_MANS = \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
-   ndctl-disable-passphrase.1
+   ndctl-disable-passphrase.1 \
+   ndctl-freeze-security.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-freeze-security.txt 
b/Documentation/ndctl/ndctl-freeze-security.txt
new file mode 100644
index ..4e9d2d61
--- /dev/null
+++ b/Documentation/ndctl/ndctl-freeze-security.txt
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-freeze-security(1)
+
+
+NAME
+
+ndctl-freeze-security - enabling or freeze the security for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl freeze-security' 
+
+DESCRIPTION
+---
+Provide a generic interface to freeze the security for NVDIMM. Once security
+is frozen, no other security operations can succeed until reboot happens.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 821ea690..f7469598 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -35,4 +35,5 @@ int cmd_inject_smart(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4f0466a1..19301791 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -876,6 +876,24 @@ static int action_passphrase_disable(struct ndctl_dimm 
*dimm,
return ndctl_dimm_disable_key(dimm, param.key_path);
 }
 
+static int action_security_freeze(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_freeze_security(dimm);
+   if (rc < 0)
+   error("Failed to freeze security for %s\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1285,3 +1303,13 @@ int cmd_disable_passphrase(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_freeze_security(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_security_freeze, 
base_options,
+   "ndctl freeze-security  [..] 
[]");
+
+   fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 076ccbf6..8f0f0486 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -672,3 +672,8 @@ NDCTL_EXPORT int ndctl_dimm_disable_passphrase(struct 
ndctl_dimm *dimm,
sprintf(buf, "disable %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm)
+{
+   return write_security(dimm, "freeze");
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 90038e75..a1c56060 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -395,4 +395,5 @@ global:
ndctl_dimm_update_passphrase;
ndctl_dimm_disable_passphrase;
ndctl_dimm_disable_key;
+   ndctl_dimm_freeze_security;
 } LIBNDCTL_18;
diff --git a/ndctl/libn

[PATCH v8 01/12] ndctl: add support for display security state

2019-01-14 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   37 
 ndctl/lib/libndctl.sym |5 +
 ndctl/libndctl.h   |   13 +
 util/json.c|   31 ++
 5 files changed, 94 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0a..e03135d9 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -587,3 +587,40 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *state)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return -ERANGE;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return rc;
+
+   if (strcmp(buf, "unsupported") == 0)
+   *state = ND_SECURITY_UNSUPPORTED;
+   else if (strcmp(buf, "disabled") == 0)
+   *state = ND_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   *state = ND_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   *state = ND_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   *state = ND_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   *state = ND_SECURITY_OVERWRITE;
+   else
+   *state = ND_SECURITY_INVALID;
+
+   return 0;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6c4c8b4d..1bd63fa1 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -385,3 +385,8 @@ global:
ndctl_namespace_get_next_badblock;
ndctl_dimm_get_dirty_shutdown;
 } LIBNDCTL_17;
+
+LIBNDCTL_19 {
+global:
+   ndctl_dimm_get_security;
+} LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index c81cc032..4255252c 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -681,6 +681,19 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct 
ndctl_cmd *cmd);
 struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm 
*dimm);
 int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm);
 
+enum nd_security_state {
+   ND_SECURITY_INVALID = -1,
+   ND_SECURITY_UNSUPPORTED = 0,
+   ND_SECURITY_DISABLED,
+   ND_SECURITY_UNLOCKED,
+   ND_SECURITY_LOCKED,
+   ND_SECURITY_FROZEN,
+   ND_SECURITY_OVERWRITE,
+};
+
+int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *sstate);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..e3b9e72e 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum nd_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,36 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   if (ndctl_dimm_get_security(dimm, ) == 0) {
+   switch (sstate) {
+   case ND_SECURITY_UNSUPPORTED:
+   jobj = json_object_new_string("unsupported");
+   break;
+   case ND_SECURITY_DISABLED:
+   jobj = json_object_new_string("disabled");
+   break;
+   case ND_SECURITY_UNLOCKED:
+   jobj = json_object_new_string("unlocked");
+   break;
+ 

[PATCH v7 10/12] ndctl: master phassphrase management support

2019-01-09 Thread Dave Jiang
Adding master passphrase enabling and update to ndctl. This is a new
feature from Intel DSM v1.8.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-enable-passphrase.txt |7 +
 Documentation/ndctl/ndctl-update-passphrase.txt |7 +
 ndctl/dimm.c|   13 +-
 ndctl/lib/dimm.c|9 ++
 ndctl/lib/keys.c|  127 ---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|   14 ++-
 7 files changed, 130 insertions(+), 48 deletions(-)

diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
index c14a206c..c025b1c3 100644
--- a/Documentation/ndctl/ndctl-enable-passphrase.txt
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -29,7 +29,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master=::
+--master-key=::
Key name for the master key used to seal the NVDIMM security keys.
The format would be :
i.e.: trusted:master-nvdimm
@@ -39,4 +39,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Indicates that we are managing the master passphrase instead of the
+   user passphrase.
+
 include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
index dd6e4e4e..8b5dfe01 100644
--- a/Documentation/ndctl/ndctl-update-passphrase.txt
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -26,7 +26,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master::
+--master-key=::
New key name for the master key to seal the new nvdimm key, or the
existing master key name. i.e trusted:master-key.
 
@@ -35,4 +35,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index ce477981..4875e414 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -49,6 +49,7 @@ static struct parameters {
const char *master_key;
bool crypto_erase;
bool overwrite;
+   bool master_pass;
bool force;
bool json;
bool verbose;
@@ -849,8 +850,8 @@ static int action_key_enable(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_enable_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_enable_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_key_update(struct ndctl_dimm *dimm,
@@ -862,8 +863,8 @@ static int action_key_update(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_update_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_update_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_disable(struct ndctl_dimm *dimm,
@@ -1044,7 +1045,9 @@ OPT_FILENAME('p', "key-path", _path, 
"key-path", \
 
 #define KEY_OPTIONS() \
 OPT_STRING('m', "master-key", _key, ":", \
-   "master key for security")
+   "master key for security"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 #define SANITIZE_OPTIONS() \
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index eb950331..dc945296 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -771,3 +771,12 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
ndctl_dimm *dimm)
close(fd);
return rc;
 }
+
+NDCTL_EXPORT int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
+   long ckey, long nkey)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 2eb23d38..fc71cc2b 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -21,7 +21,7 @@
 #define KEY_CMD_SIZE   128
 
 static int get_key_path(struct ndctl_dimm *dimm, char *path,
-   enum ndctl_key_type key_type, const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
char hostname[HOST_NAME_MAX];
@@ -33,16 

[PATCH v7 12/12] ndctl: documentation for security and key management

2019-01-09 Thread Dave Jiang
Add a "Theory of Operation" section describing the Intel DSM operations to
the relevant man pages.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |2 
 Documentation/ndctl/ndctl-enable-passphrase.txt  |2 
 Documentation/ndctl/ndctl-freeze-security.txt|2 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |2 
 Documentation/ndctl/ndctl-update-passphrase.txt  |2 
 6 files changed, 150 insertions(+)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt

diff --git a/Documentation/ndctl/intel-nvdimm-security.txt 
b/Documentation/ndctl/intel-nvdimm-security.txt
new file mode 100644
index ..b8443e12
--- /dev/null
+++ b/Documentation/ndctl/intel-nvdimm-security.txt
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+
+THEORY OF OPERATOIN
+---
+With the introduction of Intel Device Specific Methods (DSM) specification
+v1.7 and v1.8 [1], security DSMs were introduced. The operations supported by 
+ndctl are enable passhprase, update passphrase, disable security,
+freeze security, secure (crypto) erase, overwrite, master passphrase enable,
+master passphrase update, and master passphrase secure (crypto) erase.
+The 'unlock' DSM is not supported by ndctl, that is left for the kernel to
+manage with some assistance from userspace.
+
+The security management for nvdimm is composed of two parts. The front end
+utilizes the Linux key management framework (trusted and encrypted keys [2]).
+It uses the keyutils on the user side and Linux key management APIs in
+the kernel. The backend takes the decrypted payload of the key and passes the
+plaintext payload to the nvdimm for processing.
+
+Unlike typical DSMs, the security DSMs are managed through the 'security'
+sysfs attribute under the dimm devices rather than an ioctl call by libndctl.
+The relevant key id is written to the 'security' attribute and the kernel will
+pull that key from the kernel's user key ring for processing.
+
+The entire security process starts with a master key that is used to seal the
+encrypted keys that are used to protect the passphrase for each nvdimm. We
+recommend using the *system* master key from the Trusted Platform
+Module (TPM), but a master key generated by the TPM can also
+be used. For testing purposes a user key with randomized payload can
+also be served as a master key. See [2] for details. To perform any security
+operations, it is expected that at the minimum the master key is already
+in the kernel's user keyring as shown in example below:
+
+> keyctl show
+Session Keyring
+ 736023423 --alswrv  0 0  keyring: _ses
+ 675104189 --alswrv  0 65534   \_ keyring: _uid.0
+ 680187394 --alswrv  0 0   \_ trusted: nvdimm-master
+
+Except for 'overwrite', all operations expect the relevant regions associated
+with the nvdimm are disabled before proceeding. For 'overwrite', in addition
+to the regions, the dimm itself is expected to be disabled.
+
+The following sections describe specifics of each security features.
+
+UNLOCK
+--
+Unlock is performed by the kernel, however a preparation step must happen
+before the unlock DSM can be issued by the kernel. The expectation is that
+during initramfs, a setup script is called before the libnvdimm module is
+loaded by modprobe. This script script will inject the master key and the
+related encrypted keys into the kernel's user key ring. A reference modprobe
+config file and a setup script have been provided by ndctl. During the 'probe'
+of the nvdimm driver, it will:
+1. First, check the security state of the device and see if the DIMM is locked
+2. Request the associated encrypted key from the kernel's user key ring.
+3. Finally, create the unlock DSM, copy the decrypted payload into the DSM
+   passphrase field, and issue the DSM to unlock the DIMM.
+
+If the DIMM is already unlocked, the kernel will attempt to revalidate the key.
+This can be overriden with a kernel module parameter. If we fail to revalidate
+the key, the kernel will freeze the security and disallow any further security
+configuration changes.
+
+ENABLE USER PASSPHRASE
+--
+To enable the user passphrase for a DIMM, it is expected that the master key
+is already in the kernel's user key ring and the master key name is passed to
+ndctl so it can do key management. An encrypted key with a 32 bytes payload
+and encrypted key format 'enc32' is created and sealed by the master key. Be
+aware that the passphrase is never provided by or visible to the user.
+The decrypted payload for the encrypted key will be randomly generated by the
+kernel and userspace does not have access to this decrypted payload. When the
+encrypted key is created, a binary blob of the encrypted key is written to the
+designated key blob storage directory (/etc/ndctl/keys as default). The user is
+responsible for backing up

[PATCH v7 11/12] ndctl: add master secure erase support

2019-01-09 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 ++
 ndctl/dimm.c|   14 --
 ndctl/lib/dimm.c|9 +
 ndctl/lib/keys.c|   28 +++
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|5 +++--
 6 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index d37c2a4b..f8ffb42c 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -38,4 +38,10 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4875e414..7f2d4873 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -908,6 +908,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -918,7 +924,9 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path,
+   param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1053,7 +1061,9 @@ OPT_BOOLEAN('M', "master-passphrase", _pass, 
\
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index dc945296..b9bf9cc2 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -780,3 +780,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index fc71cc2b..dba53c69 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -447,13 +447,13 @@ NDCTL_EXPORT int ndctl_dimm_update_key(struct ndctl_dimm 
*dimm,
 
 static int check_key_run_and_discard(struct ndctl_dimm *dimm,
int (*run_op)(struct ndctl_dimm *, long), const char *name,
-   const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
key_serial_t key;
int rc;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
key = dimm_load_key(dimm, keypath, ND_USER_KEY);
if (key < 0 && run_op != ndctl_dimm_overwrite) {
@@ -470,8 +470,12 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
return rc;
}
 
+   /* we do not delete the key if master secure erase */
+   if (key_type == ND_MASTER_KEY)
+   return 0;
+
if (key) {
-   rc = dimm_remove_key(dimm, keypath, ND_USER_KEY);
+   rc = dimm_remove_key(dimm, keypath, key_type);
if (rc < 0)
err(ctx, "Unable to cleanup key.\n");
}
@@ -482,19 +486,27 @@ NDCTL_EXPORT int ndctl_dimm_disable_key(struct ndctl_dimm 
*dimm,
const char *keypath)
 {
return check_key_run_and_discard(dimm, ndctl_dimm_disable_passphrase,

[PATCH v7 09/12] ndctl: add wait-overwrite support

2019-01-09 Thread Dave Jiang
Add a blocking 'wait-overwrite' command to ndctl to let a user wait for an
overwrite operation on a dimm to complete.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 ++
 ndctl/builtin.h  |1 
 ndctl/dimm.c |   27 +
 ndctl/lib/dimm.c |   78 ++
 ndctl/lib/libndctl.sym   |1 
 ndctl/libndctl.h |1 
 ndctl/ndctl.c|1 
 8 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index bbea9674..a60a67e5 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -52,7 +52,8 @@ man1_MANS = \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
-   ndctl-sanitize-dimm.1
+   ndctl-sanitize-dimm.1 \
+   ndctl-wait-overwrite.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-wait-overwrite.txt 
b/Documentation/ndctl/ndctl-wait-overwrite.txt
new file mode 100644
index ..5d4c72ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-wait-overwrite.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-wait-overwrite(1)
+===
+
+NAME
+
+ndctl-wait-overwrite - wait for nvdimm overwrite operation to complete
+
+SYNOPSIS
+
+[verse]
+'ndctl wait-overwrite'  []
+
+DESCRIPTION
+---
+The kernel provides a POLL(2) capable sysfs file ('security') to indicate
+the state of overwrite. The 'ndctl wait-overwrite' operation waits for
+a change in the state of the 'security' file across all specified dimms.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Emit debug messages for the overwrite wait process
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+linkndctl:ndctl-sanitize-dimm[1]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 55bee47c..a8472e87 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -37,4 +37,5 @@ int cmd_passphrase_update(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_wait_overwrite(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 799823d6..ce477981 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -931,6 +931,24 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return 0;
 }
 
+static int action_wait_overwrite(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_wait_overwrite(dimm);
+   if (rc == 1)
+   printf("%s: overwrite completed.\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1378,3 +1396,12 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_overwrite(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_wait_overwrite,
+   base_options,
+   "ndctl wait-overwrite  [..] 
[]");
+
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index f27b966c..eb950331 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "private.h"
 
 static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
@@ -693,3 +694,80 @@ NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "overwrite %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   struct pollfd fds;
+   char buf[SYSFS_ATTR_SIZE];
+   int fd = 0, rc;
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len)

[PATCH v7 07/12] ndctl: setup modprobe rules

2019-01-09 Thread Dave Jiang
Adding reference config file for modprobe.d in order to trigger the
reference script that will inject keys associated with the nvdimms into
the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Makefile.am  |   10 ++
 contrib/ndctl-loadkeys.sh|   25 +
 contrib/nvdimm_modprobe.conf |1 +
 3 files changed, 36 insertions(+)
 create mode 100755 contrib/ndctl-loadkeys.sh
 create mode 100644 contrib/nvdimm_modprobe.conf

diff --git a/Makefile.am b/Makefile.am
index e0c463a3..5a3f03aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,16 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+load_key_file = contrib/ndctl-loadkeys.sh
+load_keydir = $(sysconfdir)/ndctl/
+load_key_DATA = $(load_key_file)
+EXTRA_DIST += $(load_key_file)
+
+modprobe_file = contrib/nvdimm_modprobe.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+EXTRA_DIST += $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/ndctl-loadkeys.sh b/contrib/ndctl-loadkeys.sh
new file mode 100755
index ..bc2c94df
--- /dev/null
+++ b/contrib/ndctl-loadkeys.sh
@@ -0,0 +1,25 @@
+#!/bin/bash -Ex
+
+# This script assumes a single master key for all DIMMs
+
+key_path=/etc/ndctl/keys
+tpmh_path="$key_path"/tpm.handle
+key_type=""
+tpm_handle=""
+id=""
+
+if [ -f $tpmh_path ]; then
+   key_type=trusted
+   tpm_handle="keyhandle=$(cat $tpmh_path)"
+else
+   key_type=user
+fi
+
+if ! keyctl search @u "$key_type" nvdimm-master; then
+   keyctl add "$key_type" nvdimm-master "load $(cat 
$key_path/nvdimm-master.blob) $tpm_handle" @u > /dev/null
+fi
+
+for file in "$key_path"/nvdimm_*; do
+   id="$(cut -d'_' -f2 <<< "${file##*/}")"
+   keyctl add encrypted nvdimm:"$id" "load $(cat "$file")" @u
+done
diff --git a/contrib/nvdimm_modprobe.conf b/contrib/nvdimm_modprobe.conf
new file mode 100644
index ..b113d8d7
--- /dev/null
+++ b/contrib/nvdimm_modprobe.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/sbin/ndctl-loadkeys.sh ; /sbin/modprobe 
--ignore-install libnvdimm $CMDLINE_OPTS

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


[PATCH v7 06/12] ndctl: add unit test for security ops (minus overwrite)

2019-01-09 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  203 ++
 2 files changed, 207 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..1dbe04d2
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,203 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+dev_no=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master-test"
+masterpath="$keypath/$masterkey"
+keyctl="/usr/bin/keyctl"
+
+. ./common
+
+lockpath="/sys/devices/platform/${NFIT_TEST_BUS0}/nfit_test_dimm/test_dimm"
+
+trap 'err $LINENO' ERR
+
+check_prereq()
+{
+   if [ ! -f "$keyctl" ]; then
+   echo "$keyctl does not exist."
+   exit 1
+   fi
+
+   if [ ! -d "$keypath" ]; then
+   echo "$keypath directory does not exist."
+   exit 1
+   fi
+}
+
+setup()
+{
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+}
+
+detect()
+{
+   dev=$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq .[0].dev | tr -d '"')
+   [ -n "$dev" ] || err "$LINENO"
+   id=$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq .[0].id | tr -d '"')
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   if [ ! -f "$masterpath" ]; then
+   keyctl add user $masterkey "$(dd if=/dev/urandom bs=1 count=32 
2>/dev/null)" @u
+   keyctl pipe "$(keyctl search @u user $masterkey)" > $masterpath
+   else
+   echo "Unclean setup. Please cleanup $masterpath file."
+   exit 1
+   fi
+}
+
+test_cleanup()
+{
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   rm -f "$keypath"/nvdimm_"$id"\_"$(hostname)".blob
+   rm -f "$masterpath"
+}
+
+lock_dimm()
+{
+   $NDCTL disable-dimm "$dev"
+   dev_no="$(echo "$dev" | cut -b 5-)"
+   echo 1 > "${lockpath}${dev_no}/lock_dimm"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+get_security_state()
+{
+   $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq 
.[].dimms[0].security | tr -d '"'
+}
+
+enable_passphrase()
+{
+   $NDCTL enable-passphrase -m user:"$masterkey" "$dev"
+   sstate=$(get_security_state)
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   exit 1
+   fi
+}
+
+disable_passphrase()
+{
+   $NDCTL disable-passphrase "$dev"
+   sstate=$(get_security_state)
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c "$dev"
+   sstate=$(get_security_state)
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+update_security()
+{
+   $NDCTL update-passphrase -m user:"$masterkey" "$dev"
+   sstate=$(get_security_state)
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   exit 1
+   fi
+}
+
+freeze_security()
+{
+   $NDCTL freeze-security "$dev"
+}
+
+test_1_security_enable_and_disable()
+{
+   enable_passphrase
+   disable_passphrase
+}
+
+test_2_security_enable_and_update()
+{
+   enable_passphrase
+   update_security
+   disable_passphrase
+}
+
+test_3_security_enable_and_erase()
+{
+   enable_passphrase
+   erase_security
+}
+
+test_4_security_unlocking()
+{
+   enable_passphrase
+   lock_dimm
+   $NDCTL enable-dimm &

[PATCH v7 04/12] ndctl: add support for freeze security

2019-01-09 Thread Dave Jiang
Add support for freeze security to libndctl and also command line option
of "freeze-security" for ndctl. This will lock the ability to make changes
to the NVDIMM security.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 ++-
 Documentation/ndctl/ndctl-freeze-security.txt |   20 ++
 ndctl/builtin.h   |1 +
 ndctl/dimm.c  |   28 +
 ndctl/lib/dimm.c  |5 
 ndctl/lib/libndctl.sym|1 +
 ndctl/libndctl.h  |1 +
 ndctl/ndctl.c |1 +
 8 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 31570a77..a97f193d 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -50,7 +50,8 @@ man1_MANS = \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
-   ndctl-disable-passphrase.1
+   ndctl-disable-passphrase.1 \
+   ndctl-freeze-security.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-freeze-security.txt 
b/Documentation/ndctl/ndctl-freeze-security.txt
new file mode 100644
index ..4e9d2d61
--- /dev/null
+++ b/Documentation/ndctl/ndctl-freeze-security.txt
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-freeze-security(1)
+
+
+NAME
+
+ndctl-freeze-security - enabling or freeze the security for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl freeze-security' 
+
+DESCRIPTION
+---
+Provide a generic interface to freeze the security for NVDIMM. Once security
+is frozen, no other security operations can succeed until reboot happens.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 821ea690..f7469598 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -35,4 +35,5 @@ int cmd_inject_smart(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4f0466a1..19301791 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -876,6 +876,24 @@ static int action_passphrase_disable(struct ndctl_dimm 
*dimm,
return ndctl_dimm_disable_key(dimm, param.key_path);
 }
 
+static int action_security_freeze(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_freeze_security(dimm);
+   if (rc < 0)
+   error("Failed to freeze security for %s\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1285,3 +1303,13 @@ int cmd_disable_passphrase(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_freeze_security(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_security_freeze, 
base_options,
+   "ndctl freeze-security  [..] 
[]");
+
+   fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 076ccbf6..8f0f0486 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -672,3 +672,8 @@ NDCTL_EXPORT int ndctl_dimm_disable_passphrase(struct 
ndctl_dimm *dimm,
sprintf(buf, "disable %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm)
+{
+   return write_security(dimm, "freeze");
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 90038e75..a1c56060 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -395,4 +395,5 @@ global:
ndctl_dimm_update_passphrase;
ndctl_dimm_disable_passphrase;
ndctl_dimm_disable_key;
+   ndctl_dimm_freeze_security;
 } LIBNDCTL_18;
diff --git a/ndctl/libn

[PATCH v7 01/12] ndctl: add support for display security state

2019-01-09 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   37 
 ndctl/lib/libndctl.sym |5 +
 ndctl/libndctl.h   |   13 +
 util/json.c|   31 ++
 5 files changed, 94 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0a..e03135d9 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -587,3 +587,40 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *state)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return -ERANGE;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return rc;
+
+   if (strcmp(buf, "unsupported") == 0)
+   *state = ND_SECURITY_UNSUPPORTED;
+   else if (strcmp(buf, "disabled") == 0)
+   *state = ND_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   *state = ND_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   *state = ND_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   *state = ND_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   *state = ND_SECURITY_OVERWRITE;
+   else
+   *state = ND_SECURITY_INVALID;
+
+   return 0;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6c4c8b4d..1bd63fa1 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -385,3 +385,8 @@ global:
ndctl_namespace_get_next_badblock;
ndctl_dimm_get_dirty_shutdown;
 } LIBNDCTL_17;
+
+LIBNDCTL_19 {
+global:
+   ndctl_dimm_get_security;
+} LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index c81cc032..4255252c 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -681,6 +681,19 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct 
ndctl_cmd *cmd);
 struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm 
*dimm);
 int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm);
 
+enum nd_security_state {
+   ND_SECURITY_INVALID = -1,
+   ND_SECURITY_UNSUPPORTED = 0,
+   ND_SECURITY_DISABLED,
+   ND_SECURITY_UNLOCKED,
+   ND_SECURITY_LOCKED,
+   ND_SECURITY_FROZEN,
+   ND_SECURITY_OVERWRITE,
+};
+
+int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *sstate);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..e3b9e72e 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum nd_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,36 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   if (ndctl_dimm_get_security(dimm, ) == 0) {
+   switch (sstate) {
+   case ND_SECURITY_UNSUPPORTED:
+   jobj = json_object_new_string("unsupported");
+   break;
+   case ND_SECURITY_DISABLED:
+   jobj = json_object_new_string("disabled");
+   break;
+   case ND_SECURITY_UNLOCKED:
+   jobj = json_object_new_string("unlocked");
+   break;
+ 

[PATCH v7 05/12] ndctl: add support for sanitize dimm

2019-01-09 Thread Dave Jiang
Add support to secure erase to libndctl and also command line option
of "sanitize-dimm" for ndctl. This will initiate the request to crypto
erase a DIMM.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 +-
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   37 +++
 ndctl/builtin.h |1 +
 ndctl/dimm.c|   52 +++
 ndctl/lib/dimm.c|8 
 ndctl/lib/keys.c|   21 +--
 ndctl/lib/libndctl.sym  |2 +
 ndctl/libndctl.h|9 +
 ndctl/ndctl.c   |1 +
 9 files changed, 130 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a97f193d..bbea9674 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -51,7 +51,8 @@ man1_MANS = \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
-   ndctl-freeze-security.1
+   ndctl-freeze-security.1 \
+   ndctl-sanitize-dimm.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
new file mode 100644
index ..a1eab8bc
--- /dev/null
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-sanitize-dimm(1)
+==
+
+NAME
+
+ndctl-sanitize-dimm - sanitize the data on the NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl sanitize'  []
+
+DESCRIPTION
+---
+Provide a generic interface to crypto erase a NVDIMM.
+Ndctl will search the user key ring for the associated DIMM. If no key is
+found, it will attempt to load the key blob from the expected location. Ndctl
+will remove the key and the key blob once security is disabled.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+-c::
+--crypto-erase::
+   Replaces encryption keys and securely erases the data. This does not
+   change label data. This is the default sanitize method.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index f7469598..55bee47c 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -36,4 +36,5 @@ int cmd_passphrase_setup(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 19301791..a91b40d5 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,7 @@ static struct parameters {
const char *labelversion;
const char *key_path;
const char *master_key;
+   bool crypto_erase;
bool force;
bool json;
bool verbose;
@@ -894,6 +895,35 @@ static int action_security_freeze(struct ndctl_dimm *dimm,
return rc;
 }
 
+static int action_sanitize_dimm(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   /*
+* Setting crypto erase to be default. The other method will be
+* overwrite.
+*/
+   if (!param.crypto_erase) {
+   param.crypto_erase = true;
+   printf("No santize method passed in, default to 
crypto-erase\n");
+   }
+
+   if (param.crypto_erase) {
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -991,6 +1021,10 @@ OPT_FILENAME('p', "key-path", _path, 
"key-path", \
 OPT_STRING('m', "master-key", _key, ":", \
"master key for security")
 
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('c', "crypto-erase", _erase, \
+   "crypto erase a dimm")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1033,6 +1067,13 @@ static const struct option key_options[] = {
OPT_END(),
 }

[PATCH v7 03/12] ndctl: add disable security support

2019-01-09 Thread Dave Jiang
Add support for disable security to libndctl and also command line option
of "disable-passphrase" for ndctl. This provides a way to disable security
on the nvdimm.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +-
 Documentation/ndctl/ndctl-disable-passphrase.txt |   32 +++
 ndctl/builtin.h  |1 +
 ndctl/dimm.c |   38 --
 ndctl/lib/dimm.c |9 +
 ndctl/lib/keys.c |   29 +
 ndctl/lib/libndctl.sym   |2 +
 ndctl/libndctl.h |8 +
 ndctl/ndctl.c|1 +
 9 files changed, 119 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7adb..31570a77 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -49,7 +49,8 @@ man1_MANS = \
ndctl-list.1 \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
-   ndctl-update-passphrase.1
+   ndctl-update-passphrase.1 \
+   ndctl-disable-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-disable-passphrase.txt 
b/Documentation/ndctl/ndctl-disable-passphrase.txt
new file mode 100644
index ..3c8bfe47
--- /dev/null
+++ b/Documentation/ndctl/ndctl-disable-passphrase.txt
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-disable-passphrase(1)
+===
+
+NAME
+
+ndctl-disable-passphrase - disabling passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl disable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a generic interface for disabling passphrase for NVDIMM.
+Ndctl will search the user key ring for the associated DIMM. If no key is
+found, it will attempt to load the key blob from the expected location. Ndctl
+will remove the key and the key blob once passphrase is disabled.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 231fda25..821ea690 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -34,4 +34,5 @@ int cmd_update_firmware(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 1ab6b29f..4f0466a1 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -864,6 +864,18 @@ static int action_key_update(struct ndctl_dimm *dimm,
param.key_path);
 }
 
+static int action_passphrase_disable(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   return ndctl_dimm_disable_key(dimm, param.key_path);
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -953,12 +965,14 @@ OPT_BOOLEAN('f', "force", , \
 OPT_STRING('V', "label-version", , "version-number", \
"namespace label specification version (default: 1.1)")
 
-#define KEY_OPTIONS() \
-OPT_STRING('m', "master-key", _key, ":", \
-   "master key for security"), \
+#define KEY_BASE_OPTIONS() \
 OPT_FILENAME('p', "key-path", _path, "key-path", \
"override the default key path")
 
+#define KEY_OPTIONS() \
+OPT_STRING('m', "master-key", _key, ":", \
+   "master key for security")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -988,8 +1002,15 @@ static const struct option init_options[] = {
OPT_END(),
 };
 
+static const struct option key_base_options[] = {
+   BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
+   OPT_END(),
+};
+
 static const struct option key_options[] = {
BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
KEY_OPTIONS(),
OPT_END(),
 };
@@ -1253,3 +1274,14 @@ int cmd_passphrase_setup(int argc, const char **argv, 
struct ndctl_ctx *ctx)
count > 1

[PATCH v7 02/12] ndctl: add passphrase update to ndctl

2019-01-09 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |4 
 Documentation/ndctl/ndctl-enable-passphrase.txt |   42 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   38 ++
 configure.ac|   19 +
 ndctl.spec.in   |2 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |2 
 ndctl/dimm.c|   94 +
 ndctl/lib/Makefile.am   |8 
 ndctl/lib/dimm.c|   39 ++
 ndctl/lib/keys.c|  394 +++
 ndctl/lib/libndctl.sym  |4 
 ndctl/libndctl.h|   32 ++
 ndctl/ndctl.c   |2 
 14 files changed, 670 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/lib/keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a30b139b..7adb 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,9 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-enable-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
new file mode 100644
index ..c14a206c
--- /dev/null
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-enable-passphrase(1)
+==
+
+NAME
+
+ndctl-enable-passphrase - enable the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl enable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to enable the security passphrase for the NVDIMM.
+It is expected that the master key has already been loaded into the user
+key ring. The encrypted key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in /etc/nvdimm. Do not touch the /etc/nvdimm
+directory and let ndctl manage the keys, unless you know what you are doing.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master=::
+   Key name for the master key used to seal the NVDIMM security keys.
+   The format would be :
+   i.e.: trusted:master-nvdimm
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..dd6e4e4e
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to update the security key for NVDIMM.
+It is expected that the current and the new (if new master key is desired)
+master key has already been loaded into the user key ring. The new encrypted
+key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master::
+   New key name for the master key to seal the new nvdimm key, or the
+   existing master key name. i.e trusted:master-key.
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/configure.ac b/configure.ac
index aa07ec7b..22efc871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,6 +154,7 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
+
 ndctl_monitorconfdir=${sysconfdir}/ndctl
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
@@ -161,6 +162,24 @@ AC_SUBST([ndctl_monitorconf])
 AC_DEFINE_UNQUOTED(NDCTL_CONF_FILE, 
["$ndctl_monitorconfdir/$ndctl_monitorconf"],
[default ndctl monitor conf path])
 
+AC_ARG_WITH([keyutils],
+   AS_HELP_STRING([--with-keyutils],
+   

[PATCH v7 00/12] ndctl: add security support

2019-01-09 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v7:
- Added option to provide path to key directory. (Vishal)
- Cleaned up shell scripts. (Vishal)
- Cleaned up documentation. (Vishal)
- Addressed various comments from Vishal.

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (12):
  ndctl: add support for display security state
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: setup modprobe rules
  ndctl: add overwrite operation support
  ndctl: add wait-overwrite support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am  |8 
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |   34 +
 Documentation/ndctl/ndctl-enable-passphrase.txt  |   49 ++
 Documentation/ndctl/ndctl-freeze-security.txt|   22 +
 Documentation/ndctl/ndctl-list.txt   |8 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |   49 ++
 Documentation/ndctl/ndctl-update-passphrase.txt  |   45 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 +
 Makefile.am  |   10 
 configure.ac |   19 +
 contrib/ndctl-loadkeys.sh|   25 +
 contrib/nvdimm_modprobe.conf |1 
 ndctl.spec.in|2 
 ndctl/Makefile.am|3 
 ndctl/builtin.h  |6 
 ndctl/dimm.c |  259 +++
 ndctl/lib/Makefile.am|8 
 ndctl/lib/dimm.c |  202 +
 ndctl/lib/keys.c |  512 ++
 ndctl/lib/libndctl.sym   |   19 +
 ndctl/libndctl.h |   79 +++
 ndctl/ndctl.c|6 
 test/Makefile.am |4 
 test/security.sh |  203 +
 util/json.c  |   31 +
 26 files changed, 1762 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt
 create mode 100755 contrib/ndctl-loadkeys.sh
 create mode 100644 contrib/nvdimm_modprobe.conf
 create mode 100644 ndctl/lib/keys.c
 create mode 100755 test/security.sh

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


[PATCH v6 11/12] ndctl: add master secure erase support

2018-12-14 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 +
 ndctl/dimm.c|   14 +++--
 ndctl/lib/dimm.c|9 
 ndctl/lib/keys.c|   30 ---
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|7 +-
 6 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index beb4b2f9..7b036318 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -33,4 +33,10 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index c60ef96e..b2d50e28 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -907,6 +907,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -917,7 +923,9 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm);
+   rc = ndctl_dimm_secure_erase_key(dimm,
+   param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1048,7 +1056,9 @@ OPT_BOOLEAN('M', "master-passphrase", _pass, 
\
 OPT_BOOLEAN('c', "crypto-erase", _erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", , \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", _pass, \
+   "use master passphrase")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 07513b4b..a8013e4b 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -777,3 +777,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 1d395b48..51532c7a 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -437,13 +437,14 @@ NDCTL_EXPORT int ndctl_dimm_update_key(struct ndctl_dimm 
*dimm,
 }
 
 static int check_key_run_and_discard(struct ndctl_dimm *dimm,
-   int (*run_op)(struct ndctl_dimm *, long), const char *name)
+   int (*run_op)(struct ndctl_dimm *, long), const char *name,
+   enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
key_serial_t key;
int rc;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
key = dimm_load_key(dimm, ND_USER_KEY);
if (key < 0 && run_op != ndctl_dimm_overwrite) {
@@ -460,8 +461,12 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
return rc;
}
 
+   /* we do not delete the key if master secure erase */
+   if (key_type == ND_MASTER_KEY)
+   return 0;
+
if (key) {
-   rc = dimm_remove_key(dimm, ND_USER_KEY);
+   rc = dimm_remove_key(dimm, key_type);
if (rc < 0)
err(ctx, "Unable to cleanup key.\n");
}
@@ -471,17 +476,26 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
 NDCTL_EXPORT int ndctl_dimm_disable_key(struct ndctl_dimm *dimm)
 {
return check_key_run_and_discard(dimm, ndctl_dimm_disable_passphrase,
-

[PATCH v6 06/12] ndctl: add unit test for security ops (minus overwrite)

2018-12-14 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  191 ++
 2 files changed, 195 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..5238c9c4
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,191 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+dev_no=""
+sstate=""
+KEYPATH="/etc/ndctl/keys"
+UNLOCK="/sys/devices/platform/nfit_test.0/nfit_test_dimm/test_dimm"
+MASTERKEY="nvdimm-master-test"
+MASTERPATH="$KEYPATH/$MASTERKEY"
+
+. ./common
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+   $NDCTL disable-region -b $NFIT_TEST_BUS0 all
+}
+
+detect()
+{
+   dev=$($NDCTL list -b $NFIT_TEST_BUS0 -D | jq .[0].dev | tr -d '"')
+   [ -n "$dev" ] || err "$LINENO"
+   id=$($NDCTL list -b $NFIT_TEST_BUS0 -D | jq .[0].id | tr -d '"')
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   if [ ! -f $MASTERPATH ]; then
+   keyctl add user $MASTERKEY "`dd if=/dev/urandom bs=1 count=32 
2>/dev/null`" @u
+   keyctl pipe `keyctl search @u user $MASTERKEY` > $MASTERPATH
+   else
+   echo "Unclean setup. Please cleanup $MASTERPATH file."
+   exit 1
+   fi
+}
+
+test_cleanup()
+{
+   keyctl unlink `keyctl search @u encrypted nvdimm:$id`
+   keyctl unlink `keyctl search @u user $MASTERKEY`
+   rm -f $KEYPATH/nvdimm_$id\_`hostname`.blob
+   rm -f $MASTERPATH
+}
+
+locking_dimm()
+{
+   $NDCTL disable-dimm $dev
+   dev_no=$(echo $dev | cut -b 5-)
+   echo 1 > "$UNLOCK$dev_no/lock_dimm"
+   get_security_state
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+get_security_state()
+{
+   sstate=$($NDCTL list -i -b $NFIT_TEST_BUS0 -d $dev | jq 
.[].dimms[0].security | tr -d '"')
+   [ -n "$sstate" ] || err "$LINENO"
+}
+
+enable_passphrase()
+{
+   $NDCTL enable-passphrase -m user:$MASTERKEY $dev
+   get_security_state
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   exit 1
+   fi
+}
+
+disable_passphrase()
+{
+   $NDCTL disable-passphrase $dev
+   get_security_state
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c $dev
+   get_security_state
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   exit 1
+   fi
+}
+
+update_security()
+{
+   $NDCTL update-passphrase -m user:$MASTERKEY $dev
+   get_security_state
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   exit 1
+   fi
+}
+
+freeze_security()
+{
+   $NDCTL freeze-security $dev
+}
+
+test_1_security_enable_and_disable()
+{
+   enable_passphrase
+   disable_passphrase
+}
+
+test_2_security_enable_and_update()
+{
+   enable_passphrase
+   update_security
+   disable_passphrase
+}
+
+test_3_security_enable_and_erase()
+{
+   enable_passphrase
+   erase_security
+}
+
+test_4_security_unlocking()
+{
+   enable_passphrase
+   locking_dimm
+   $NDCTL enable-dimm $dev
+   get_security_state
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   exit 1
+   fi
+   $NDCTL disable-region -b $NFIT_TEST_BUS0 all
+   disable_passphrase
+}
+
+# this should always be the last test. with security frozen, nfit_test must
+# be removed and is no longer usable
+test_5_security_freeze()
+{
+   enable_passphrase
+   freeze_security
+   get_security_state
+   if [ "$sstate" != "frozen" ]; then
+   echo "Incor

[PATCH v6 07/12] ndctl: setup modprobe rules

2018-12-14 Thread Dave Jiang
Adding reference config file for modprobe.d in order to trigger the
reference script that will inject keys associated with the nvdimms into
the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Makefile.am  |   10 ++
 contrib/ndctl-loadkeys.sh|   24 
 contrib/nvdimm_modprobe.conf |1 +
 3 files changed, 35 insertions(+)
 create mode 100755 contrib/ndctl-loadkeys.sh
 create mode 100644 contrib/nvdimm_modprobe.conf

diff --git a/Makefile.am b/Makefile.am
index e0c463a3..5a3f03aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,16 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+load_key_file = contrib/ndctl-loadkeys.sh
+load_keydir = $(sysconfdir)/ndctl/
+load_key_DATA = $(load_key_file)
+EXTRA_DIST += $(load_key_file)
+
+modprobe_file = contrib/nvdimm_modprobe.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+EXTRA_DIST += $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/ndctl-loadkeys.sh b/contrib/ndctl-loadkeys.sh
new file mode 100755
index ..dae0a88a
--- /dev/null
+++ b/contrib/ndctl-loadkeys.sh
@@ -0,0 +1,24 @@
+#!/bin/bash -Ex
+
+# This script assumes a single master key for all DIMMs
+
+KEY_PATH=/etc/ndctl/keys
+TPMH_PATH=$KEY_PATH/tpm.handle
+KEYTPE=""
+TPM_HANDLE=""
+id=""
+
+if [ -f $TPMH_PATH ]; then
+   KEYTYPE=trusted
+   TPM_HANDLE="keyhandle=`cat $TPMH_PATH`"
+else
+   KEYTYPE=user
+fi
+
+keyctl show | grep -q nvdimm-master || keyctl add $KEYTYPE nvdimm-master "load 
`cat $KEY_PATH/nvdimm-master.blob` $TPM_HANDLE" @u > /dev/null
+
+for i in `ls -1 $KEY_PATH/nvdimm_*.blob`;
+do
+   id=`echo $i | cut -d'_' -f2`
+   keyctl add encrypted nvdimm:$id "load `cat $i`" @u
+done
diff --git a/contrib/nvdimm_modprobe.conf b/contrib/nvdimm_modprobe.conf
new file mode 100644
index ..b113d8d7
--- /dev/null
+++ b/contrib/nvdimm_modprobe.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/sbin/ndctl-loadkeys.sh ; /sbin/modprobe 
--ignore-install libnvdimm $CMDLINE_OPTS

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


[PATCH v6 01/12] ndctl: add support for display security state

2018-12-14 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   37 
 ndctl/lib/libndctl.sym |5 +
 ndctl/libndctl.h   |   13 +
 util/json.c|   31 ++
 5 files changed, 94 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 5e41734d..cd2895c9 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -583,3 +583,40 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *state)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return -ERANGE;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return rc;
+
+   if (strcmp(buf, "unsupported") == 0)
+   *state = ND_SECURITY_UNSUPPORTED;
+   else if (strcmp(buf, "disabled") == 0)
+   *state = ND_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   *state = ND_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   *state = ND_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   *state = ND_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   *state = ND_SECURITY_OVERWRITE;
+   else
+   *state = ND_SECURITY_INVALID;
+
+   return 0;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6c4c8b4d..1bd63fa1 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -385,3 +385,8 @@ global:
ndctl_namespace_get_next_badblock;
ndctl_dimm_get_dirty_shutdown;
 } LIBNDCTL_17;
+
+LIBNDCTL_19 {
+global:
+   ndctl_dimm_get_security;
+} LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 62cef9e8..a9f9167a 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -681,6 +681,19 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct 
ndctl_cmd *cmd);
 struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm 
*dimm);
 int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm);
 
+enum nd_security_state {
+   ND_SECURITY_INVALID = -1,
+   ND_SECURITY_UNSUPPORTED = 0,
+   ND_SECURITY_DISABLED,
+   ND_SECURITY_UNLOCKED,
+   ND_SECURITY_LOCKED,
+   ND_SECURITY_FROZEN,
+   ND_SECURITY_OVERWRITE,
+};
+
+int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *sstate);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..e3b9e72e 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum nd_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,36 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   if (ndctl_dimm_get_security(dimm, ) == 0) {
+   switch (sstate) {
+   case ND_SECURITY_UNSUPPORTED:
+   jobj = json_object_new_string("unsupported");
+   break;
+   case ND_SECURITY_DISABLED:
+   jobj = json_object_new_string("disabled");
+   break;
+   case ND_SECURITY_UNLOCKED:
+   jobj = json_object_new_string("unlocked");
+   break;
+ 

[PATCH v6 00/12] ndctl: add security support

2018-12-14 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (12):
  ndctl: add support for display security state
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: setup modprobe rules
  ndctl: add overwrite operation support
  ndctl: add overwrite-wait support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am  |8 
 Documentation/ndctl/intel-nvdimm-security.txt|  139 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |   29 +
 Documentation/ndctl/ndctl-enable-passphrase.txt  |   44 ++
 Documentation/ndctl/ndctl-freeze-security.txt|   22 +
 Documentation/ndctl/ndctl-list.txt   |8 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |   44 ++
 Documentation/ndctl/ndctl-update-passphrase.txt  |   40 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 +
 Makefile.am  |   10 
 builtin.h|6 
 configure.ac |   14 +
 contrib/ndctl-loadkeys.sh|   24 +
 contrib/nvdimm_modprobe.conf |1 
 ndctl.spec.in|2 
 ndctl/Makefile.am|3 
 ndctl/dimm.c |  242 ++-
 ndctl/lib/Makefile.am|8 
 ndctl/lib/dimm.c |  203 +
 ndctl/lib/keys.c |  501 ++
 ndctl/lib/libndctl.sym   |   19 +
 ndctl/libndctl.h |   76 +++
 ndctl/ndctl.c|6 
 test/Makefile.am |4 
 test/security.sh |  191 
 util/json.c  |   31 +
 26 files changed, 1693 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt
 create mode 100755 contrib/ndctl-loadkeys.sh
 create mode 100644 contrib/nvdimm_modprobe.conf
 create mode 100644 ndctl/lib/keys.c
 create mode 100755 test/security.sh

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


[PATCH v6 02/12] ndctl: add passphrase update to ndctl

2018-12-14 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |4 
 Documentation/ndctl/ndctl-enable-passphrase.txt |   35 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   33 ++
 builtin.h   |2 
 configure.ac|   14 +
 ndctl.spec.in   |2 
 ndctl/Makefile.am   |3 
 ndctl/dimm.c|   86 -
 ndctl/lib/Makefile.am   |8 
 ndctl/lib/dimm.c|   39 ++
 ndctl/lib/keys.c|  389 +++
 ndctl/lib/libndctl.sym  |4 
 ndctl/libndctl.h|   31 ++
 ndctl/ndctl.c   |2 
 14 files changed, 639 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/lib/keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a30b139b..7adb 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,9 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-enable-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
new file mode 100644
index ..8de5410c
--- /dev/null
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-enable-passphrase(1)
+==
+
+NAME
+
+ndctl-enable-passphrase - enabling the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl enable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a generic interface for enabling security for NVDIMM.
+It is expected that the master key has already been loaded into the user
+key ring. The encrypted key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in /etc/nvdimm. Do not touch the /etc/nvdimm
+directory and let ndctl manage the keys, unless you know what you are doing.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master=::
+   Key name for the master key used to seal the NVDIMM security keys.
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..9ed39cca
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  []
+
+DESCRIPTION
+---
+Provide a generic interface for updating security key for NVDIMM.
+It is expected that the current and the new (if new master key is desired)
+master key has already been loaded into the user key ring. The new encrypted
+key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master::
+   New key name for the master key to seal the new nvdimm key, or the
+   existing master key name. i.e trusted:master-key.
+
+include::../copyright.txt[]
diff --git a/builtin.h b/builtin.h
index 675a6ce7..ed018d96 100644
--- a/builtin.h
+++ b/builtin.h
@@ -48,4 +48,6 @@ int cmd_bat(int argc, const char **argv, void *ctx);
 #endif
 int cmd_update_firmware(int argc, const char **argv, void *ctx);
 int cmd_inject_smart(int argc, const char **argv, void *ctx);
+int cmd_passphrase_setup(int argc, const char **argv, void *ctx);
+int cmd_passphrase_update(int argc, const char **argv, void *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/configure.ac b/configure.ac
index bb6b0332..ac4f56c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,6 +153,20 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
+AC_ARG_WITH([keyutils],
+   AS_HELP_STRING([--with-keyutils],
+   [Enable keyutils functionality (security).  
@<:@default=yes@:>@]), [], [with_keyutils=yes])
+
+if test "x$with_keyutils" = "xyes"; then
+

  1   2   3   4   5   6   7   8   9   >