Commit ee164e62 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

nvmf/tcp: use keyring for retrieving PSKs



It is now possible to retrieve TLS PSKs from the keyring.  The previous
method of specifying a path to a file containing the key is still
functional, but it's deprecated and will be removed in the future.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Iea1ff6918056f910f0fc3e030886cdba1e24b7e9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/21757


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 2cbc8aec
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -65,6 +65,12 @@ will be removed in 24.05 release.
The function is deprecated and will be removed in 24.05 release. Please use
`spdk_nvmf_subsystem_any_listener_allowed` instead.

#### `nvmf_subsystem_add_host`

The ability to specifying path to a PSK file via the `psk` parameter in `nvmf_subsystem_add_host` is
deprecated and will be removed in the v24.09 release.  Instead, the name of a key attached to the
keyring should be used.

### gpt

#### `old_gpt_guid`
+36 −16
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "spdk/trace.h"
#include "spdk/util.h"
#include "spdk/log.h"
#include "spdk/keyring.h"

#include "spdk_internal/assert.h"
#include "spdk_internal/nvme_tcp.h"
@@ -353,6 +354,7 @@ struct tcp_psk_entry {
	char				subnqn[SPDK_NVMF_NQN_MAX_LEN + 1];
	char				pskid[NVMF_PSK_IDENTITY_LEN];
	uint8_t				psk[SPDK_TLS_PSK_MAX_LEN];
	struct spdk_key			*key;

	/* Original path saved to emit SPDK configuration via "save_config". */
	char				psk_path[PATH_MAX];
@@ -608,6 +610,7 @@ nvmf_tcp_free_psk_entry(struct tcp_psk_entry *entry)
	}

	spdk_memset_s(entry->psk, sizeof(entry->psk), 0, sizeof(entry->psk));
	spdk_keyring_put_key(entry->key);
	free(entry);
}

@@ -3581,6 +3584,8 @@ tcp_load_psk(const char *fname, char *buf, size_t bufsz)
	return 0;
}

SPDK_LOG_DEPRECATION_REGISTER(nvmf_tcp_psk_path, "PSK path", "v24.09", 0);

static int
nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
			    const struct spdk_nvmf_subsystem *subsystem,
@@ -3606,7 +3611,7 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,

	memset(&opts, 0, sizeof(opts));

	/* Decode PSK file path */
	/* Decode PSK (either name of a key or file path) */
	if (spdk_json_decode_object_relaxed(transport_specific, tcp_subsystem_add_host_opts_decoder,
					    SPDK_COUNTOF(tcp_subsystem_add_host_opts_decoder), &opts)) {
		SPDK_ERRLOG("spdk_json_decode_object failed\n");
@@ -3624,6 +3629,15 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
		goto end;
	}

	entry->key = spdk_keyring_get_key(opts.psk);
	if (entry->key != NULL) {
		rc = spdk_key_get_key(entry->key, psk_interchange, SPDK_TLS_PSK_MAX_LEN);
		if (rc < 0) {
			SPDK_ERRLOG("Failed to retreive PSK '%s'\n", opts.psk);
			rc = -EINVAL;
			goto end;
		}
	} else {
		if (strlen(opts.psk) >= sizeof(entry->psk)) {
			SPDK_ERRLOG("PSK path too long\n");
			rc = -EINVAL;
@@ -3636,6 +3650,9 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
			goto end;
		}

		SPDK_LOG_DEPRECATED(nvmf_tcp_psk_path);
	}

	/* Parse PSK interchange to get length of base64 encoded data.
	 * This is then used to decide which cipher suite should be used
	 * to generate PSK identity and TLS PSK later on. */
@@ -3705,12 +3722,14 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
		entry->psk_size = rc;
	}

	if (entry->key == NULL) {
		rc = snprintf(entry->psk_path, sizeof(entry->psk_path), "%s", opts.psk);
		if (rc < 0 || (size_t)rc >= sizeof(entry->psk_path)) {
			SPDK_ERRLOG("Could not save PSK path!\n");
			rc = -ENAMETOOLONG;
			goto end;
		}
	}

	TAILQ_INSERT_TAIL(&ttransport->psks, entry, link);
	rc = 0;
@@ -3764,7 +3783,8 @@ nvmf_tcp_subsystem_dump_host(struct spdk_nvmf_transport *transport,
	TAILQ_FOREACH(entry, &ttransport->psks, link) {
		if ((strncmp(entry->hostnqn, hostnqn, SPDK_NVMF_NQN_MAX_LEN)) == 0 &&
		    (strncmp(entry->subnqn, subsystem->subnqn, SPDK_NVMF_NQN_MAX_LEN)) == 0) {
			spdk_json_write_named_string(w, "psk", entry->psk_path);
			spdk_json_write_named_string(w, "psk", entry->key ?
						     spdk_key_get_name(entry->key) : entry->psk_path);
			break;
		}
	}
+3 −2
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ DEPDIRS-nbd := log util thread $(JSON_LIBS) bdev
ifeq ($(CONFIG_UBLK),y)
DEPDIRS-ublk := log util thread $(JSON_LIBS) bdev
endif
DEPDIRS-nvmf := accel log sock util nvme thread $(JSON_LIBS) trace bdev
DEPDIRS-nvmf := accel log sock util nvme thread $(JSON_LIBS) trace bdev keyring
ifeq ($(CONFIG_RDMA),y)
DEPDIRS-nvmf += rdma
endif
@@ -176,7 +176,8 @@ DEPDIRS-event_nbd := init nbd event_bdev
ifeq ($(CONFIG_UBLK),y)
DEPDIRS-event_ublk := init ublk event_bdev
endif
DEPDIRS-event_nvmf := init nvmf event_bdev event_scheduler event_sock thread log bdev util $(JSON_LIBS)
DEPDIRS-event_nvmf := init nvmf event_bdev event_scheduler event_sock event_keyring \
		      thread log bdev util $(JSON_LIBS)
DEPDIRS-event_scsi := init scsi event_bdev

DEPDIRS-event_iscsi := init iscsi event_scheduler event_scsi event_sock
+1 −0
Original line number Diff line number Diff line
@@ -583,4 +583,5 @@ static struct spdk_subsystem g_spdk_subsystem_nvmf = {

SPDK_SUBSYSTEM_REGISTER(g_spdk_subsystem_nvmf)
SPDK_SUBSYSTEM_DEPEND(nvmf, bdev)
SPDK_SUBSYSTEM_DEPEND(nvmf, keyring)
SPDK_SUBSYSTEM_DEPEND(nvmf, sock)
+44 −0
Original line number Diff line number Diff line
@@ -231,5 +231,49 @@ waitforlisten "$bdevperf_pid" "$bdevperf_rpc_sock"

"$rootdir/examples/bdev/bdevperf/bdevperf.py" -s "$bdevperf_rpc_sock" perform_tests

killprocess $bdevperf_pid
killprocess $nvmfpid

# Check the same, but this time, use keyring on the target side too
nvmfappstart
rpc_cmd << CONFIG
	nvmf_create_transport $NVMF_TRANSPORT_OPTS
	bdev_malloc_create 32 4096 -b malloc0
	nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1
	nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t tcp \
		-a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -k
	nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 malloc0
	keyring_file_add_key key0 "$key_long_path"
	nvmf_subsystem_add_host nqn.2016-06.io.spdk:cnode1 nqn.2016-06.io.spdk:host1 --psk key0
CONFIG

"$rootdir/build/examples/bdevperf" -m 2 -z -r "$bdevperf_rpc_sock" \
	-q 128 -o 4k -w verify -t 1 "${NO_HUGE[@]}" &
bdevperf_pid=$!

waitforlisten "$bdevperf_pid" "$bdevperf_rpc_sock"
"$rpc_py" -s "$bdevperf_rpc_sock" keyring_file_add_key key0 "$key_long_path"
"$rpc_py" -s "$bdevperf_rpc_sock" bdev_nvme_attach_controller -b nvme0 -t tcp \
	-a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -f ipv4 --psk key0 \
	-n "nqn.2016-06.io.spdk:cnode1" -q "nqn.2016-06.io.spdk:host1"

"$rootdir/examples/bdev/bdevperf/bdevperf.py" -s "$bdevperf_rpc_sock" perform_tests

# Check save/load config
tgtcfg=$(rpc_cmd save_config)
bperfcfg=$("$rpc_py" -s "$bdevperf_rpc_sock" save_config)

killprocess $bdevperf_pid
killprocess $nvmfpid

nvmfappstart -c <(echo "$tgtcfg")
"$rootdir/build/examples/bdevperf" -m 2 -z -r "$bdevperf_rpc_sock" \
	-q 128 -o 4k -w verify -t 1 "${NO_HUGE[@]}" -c <(echo "$bperfcfg") &
bdevperf_pid=$!
waitforlisten "$bdevperf_pid" "$bdevperf_rpc_sock"

[[ $("$rpc_py" -s "$bdevperf_rpc_sock" bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]]
"$rootdir/examples/bdev/bdevperf/bdevperf.py" -s "$bdevperf_rpc_sock" perform_tests

trap - SIGINT SIGTERM EXIT
cleanup
Loading