All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Jiang <dave.jiang@intel.com>
To: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev
Cc: vishal.l.verma@intel.com
Subject: [PATCH 4/4] ndctl/test: Add CXL test for security
Date: Wed, 21 Sep 2022 14:02:58 -0700	[thread overview]
Message-ID: <166379417897.433612.16268594042547006566.stgit@djiang5-desk3.ch.intel.com> (raw)
In-Reply-To: <166379397620.433612.13099557870939895846.stgit@djiang5-desk3.ch.intel.com>

Create security-cxl.sh based off of security.sh for nfit security testing.
The test will test a cxl_test based security commands enabling through
nvdimm.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 test/common          |    7 +
 test/meson.build     |    7 +
 test/security-cxl.sh |  282 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100755 test/security-cxl.sh

diff --git a/test/common b/test/common
index 65615cc09a3e..e13b79728b0c 100644
--- a/test/common
+++ b/test/common
@@ -47,6 +47,7 @@ fi
 #
 NFIT_TEST_BUS0="nfit_test.0"
 NFIT_TEST_BUS1="nfit_test.1"
+CXL_TEST_BUS="cxl_test"
 ACPI_BUS="ACPI.NFIT"
 E820_BUS="e820"
 
@@ -125,6 +126,12 @@ _cleanup()
 	modprobe -r nfit_test
 }
 
+_cxl_cleanup()
+{
+	$NDCTL disable-region -b $CXL_TEST_BUS all
+	modprobe -r cxl_test
+}
+
 # json2var
 # stdin: json
 #
diff --git a/test/meson.build b/test/meson.build
index 5953c286d13f..485deb89bbe2 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -219,6 +219,13 @@ if get_option('keyutils').enabled()
   ]
 endif
 
+if get_option('keyutils').enabled()
+  security_cxl = find_program('security-cxl.sh')
+  tests += [
+    [ 'security-cxl.sh', security_cxl, 'ndctl' ]
+  ]
+endif
+
 foreach t : tests
   test(t[0], t[1],
     is_parallel : false,
diff --git a/test/security-cxl.sh b/test/security-cxl.sh
new file mode 100755
index 000000000000..0ec9b335bf41
--- /dev/null
+++ b/test/security-cxl.sh
@@ -0,0 +1,282 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2022 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master"
+masterpath="$keypath/$masterkey.blob"
+backup_key=0
+backup_handle=0
+
+. $(dirname $0)/common
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+	$NDCTL disable-region -b "$CXL_TEST_BUS" all
+}
+
+detect()
+{
+	dev="$($NDCTL list -b "$CXL_TEST_BUS" -D | jq -r 'sort_by(.id) | .[0].dev')"
+	[ -n "$dev" ] || err "$LINENO"
+	id="$($NDCTL list -b "$CXL_TEST_BUS" -D | jq -r 'sort_by(.id) | .[0].id')"
+	[ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+	if [ ! -d "$keypath" ]; then
+		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/tpm.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"
+}
+
+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
+}
+
+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/tpm.handle"
+	fi
+}
+
+lock_dimm()
+{
+	$NDCTL disable-dimm "$dev"
+	test_dimm_path=""
+
+	nmem_rpath=$(readlink -f "/sys/bus/nd/devices/${dev}")
+	nmem_bus=$(dirname ${nmem_rpath});
+	bus_provider_path="${nmem_bus}/provider"
+	test -e "$bus_provider_path" || err "$LINENO"
+	bus_provider=$(cat ${bus_provider_path})
+
+	[[ "$bus_provider" == "$CXL_TEST_BUS" ]] || err "$LINENO"
+	bus="cxl"
+	nmem_provider_path="/sys/bus/nd/devices/${dev}/${bus}/provider"
+	nmem_provider=$(cat ${nmem_provider_path})
+
+	test_dimm_path=$(readlink -f /sys/bus/$bus/devices/${nmem_provider})
+	test_dimm_path=$(dirname $(dirname ${test_dimm_path}))/security_lock
+
+	test -e "$test_dimm_path"
+
+	# now lock the dimm
+	echo 1 > "${test_dimm_path}"
+	sstate="$(get_security_state)"
+	if [ "$sstate" != "locked" ]; then
+		echo "Incorrect security state: $sstate expected: locked"
+		err "$LINENO"
+	fi
+}
+
+get_frozen_state()
+{
+	$NDCTL list -i -b "$CXL_TEST_BUS" -d "$dev" | jq -r .[].dimms[0].security_frozen
+}
+
+get_security_state()
+{
+	$NDCTL list -i -b "$CXL_TEST_BUS" -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 "Incorrect security state: $sstate expected: disabled"
+		err "$LINENO"
+	fi
+}
+
+update_security()
+{
+	$NDCTL update-passphrase "$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_setup_and_remove()
+{
+	setup_passphrase
+	remove_passphrase
+}
+
+test_2_security_setup_and_update()
+{
+	setup_passphrase
+	update_security
+	remove_passphrase
+}
+
+test_3_security_setup_and_erase()
+{
+	setup_passphrase
+	erase_security
+}
+
+test_4_security_unlock()
+{
+	setup_passphrase
+	lock_dimm
+	$NDCTL enable-dimm "$dev"
+	sstate="$(get_security_state)"
+	if [ "$sstate" != "unlocked" ]; then
+		echo "Incorrect security state: $sstate expected: unlocked"
+		err "$LINENO"
+	fi
+	$NDCTL disable-region -b "$CXL_TEST_BUS" all
+	remove_passphrase
+}
+
+# This should always be the last nvdimm security test.
+# with security frozen, cxl_test must be removed and is no longer usable
+test_5_security_freeze()
+{
+	setup_passphrase
+	freeze_security
+	sstate="$(get_security_state)"
+	fstate="$(get_frozen_state)"
+	if [ "$fstate" != "true" ]; then
+		echo "Incorrect security state: expected: frozen"
+		err "$LINENO"
+	fi
+
+	# need to simulate a soft reboot here to clean up
+	lock_dimm
+	$NDCTL enable-dimm "$dev"
+	sstate="$(get_security_state)"
+	if [ "$sstate" != "unlocked" ]; then
+		echo "Incorrect security state: $sstate expected: unlocked"
+		err "$LINENO"
+	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
+	do_skip "run as root or with a sudo login shell for test to work"
+fi
+
+modprobe cxl_test
+setup
+check_prereq "keyctl"
+rc=1
+detect
+test_cleanup
+setup_keys
+echo "Test 1, security setup and remove"
+test_1_security_setup_and_remove
+echo "Test 2, security setup, update, and remove"
+test_2_security_setup_and_update
+echo "Test 3, security setup and erase"
+test_3_security_setup_and_erase
+echo "Test 4, unlock dimm"
+test_4_security_unlock
+
+# Freeze should always be the last nvdimm security test because it locks
+# security state and require cxl_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
+_cxl_cleanup
+exit 0



  parent reply	other threads:[~2022-09-21 21:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-21 21:02 [PATCH 0/4] ndctl: Add security test for cxl devices through nvdimm Dave Jiang
2022-09-21 21:02 ` [PATCH 1/4] ndctl: add cxl bus detection Dave Jiang
2022-12-13 23:07   ` Verma, Vishal L
2022-12-14  2:40   ` Alison Schofield
2022-09-21 21:02 ` [PATCH 2/4] ndctl/libndctl: Add bus_prefix for cxl Dave Jiang
2022-12-13 23:10   ` Verma, Vishal L
2022-09-21 21:02 ` [PATCH 3/4] ndctl/libndctl: Add retrieving of unique_id for cxl mem dev Dave Jiang
2022-12-13 23:14   ` Verma, Vishal L
2022-09-21 21:02 ` Dave Jiang [this message]
2022-12-13 23:22   ` [PATCH 4/4] ndctl/test: Add CXL test for security Verma, Vishal L
2022-12-14  1:02   ` Dan Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=166379417897.433612.16268594042547006566.stgit@djiang5-desk3.ch.intel.com \
    --to=dave.jiang@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=nvdimm@lists.linux.dev \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.