Commit 3e98fd06 authored by Krzysztof Karas's avatar Krzysztof Karas Committed by Jim Harris
Browse files

nvme_tcp: add PSK identity generation



Add PSK identity generation based on hostnqn and subnqn
to nvme_tcp driver.

Delete hostnqn and subnqn fields from tcp_psk_entry struct.
These values are not available inside PSK identity and
can be extracted from it directly.

Additionally move PSK identity generation to nvme_tcp.h
and add a function to handle this process (psk_id_prefix
will need to be changed in the future and it will be more
convenient to edit it in a single place).

Remove --psk-identity option from perf app call in
tls.sh script and add hostnqn to let nvme_tcp driver
generate psk_identity.

Change-Id: I4a5b8cf50bd0cd1af75ab059953ebacc0a751865
Signed-off-by: default avatarKrzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15714


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
parent 9341d7bd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ authentication. Only valid for the TCP transport.
Added two optional transport module callbacks: `subsystem_add_host()` and `subsystem_remove_host()`.
These functions will notify a transport about adding/removing hosts' access.

TLS PSK identity is now generated from subsystem NQN and host NQN.

### sock

Added a callback `get_key()` to `spdk_sock_impl_opts` structure.
+0 −10
Original line number Diff line number Diff line
@@ -345,16 +345,6 @@ perf_set_sock_opts(const char *impl_name, const char *field, uint32_t val, const
			fprintf(stderr, "Failed to allocate memory for psk\n");
			return;
		}
	} else if (strcmp(field, "psk_identity") == 0) {
		if (!valstr) {
			fprintf(stderr, "No socket opts value specified\n");
			return;
		}
		sock_opts.psk_identity = strdup(valstr);
		if (sock_opts.psk_identity == NULL) {
			fprintf(stderr, "Failed to allocate psk_identity in sock_impl\n");
			return;
		}
	} else if (strcmp(field, "zerocopy_threshold") == 0) {
		sock_opts.zerocopy_threshold = val;
	} else {
+26 −0
Original line number Diff line number Diff line
@@ -561,4 +561,30 @@ nvme_tcp_pdu_calc_psh_len(struct nvme_tcp_pdu *pdu, bool hdgst_enable)
	pdu->psh_len = psh_len;
}

static inline int
nvme_tcp_generate_psk_identity(char *out_id, size_t out_id_len,
			       const char *hostnqn, const char *subnqn)
{
	/* This hardcoded PSK identity prefix will remain until
	 * support for different hash functions to generate PSK
	 * key is introduced. */
	const char *psk_id_prefix = "NVMe0R01";
	int rc;

	assert(out_id != NULL);

	if (out_id_len < strlen(psk_id_prefix) + strlen(hostnqn) + strlen(subnqn) + 3) {
		SPDK_ERRLOG("Out buffer too small!\n");
		return -1;
	}

	rc = snprintf(out_id, out_id_len, "%s %s %s", psk_id_prefix, hostnqn, subnqn);
	if (rc < 0) {
		SPDK_ERRLOG("Could not generate PSK identity\n");
		return -1;
	}

	return 0;
}

#endif /* SPDK_INTERNAL_NVME_TCP_H */
+20 −8
Original line number Diff line number Diff line
@@ -1885,9 +1885,10 @@ nvme_tcp_qpair_connect_sock(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpai
	int family;
	long int port;
	char *sock_impl_name;
	struct spdk_sock_impl_opts impl_opts;
	struct spdk_sock_impl_opts impl_opts = {};
	size_t impl_opts_size = sizeof(impl_opts);
	struct spdk_sock_opts opts;
	struct nvme_tcp_ctrlr *tcp_ctrlr;

	tqpair = nvme_tcp_qpair(qpair);

@@ -1934,14 +1935,15 @@ nvme_tcp_qpair_connect_sock(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpai
	sock_impl_name = ctrlr->opts.psk[0] ? "ssl" : NULL;
	SPDK_DEBUGLOG(nvme, "sock_impl_name is %s\n", sock_impl_name);

	if (sock_impl_name) {
		spdk_sock_impl_get_opts(sock_impl_name, &impl_opts, &impl_opts_size);
		impl_opts.enable_ktls = false;
		impl_opts.tls_version = SPDK_TLS_VERSION_1_3;
	/* TODO: Change current PSK HEX string format to TLS PSK Interchange Format */
		impl_opts.psk_key = ctrlr->opts.psk;
	/* TODO: generate identity from hostnqn instead */
	impl_opts.psk_identity = "psk.spdk.io";

		tcp_ctrlr = SPDK_CONTAINEROF(ctrlr, struct nvme_tcp_ctrlr, ctrlr);
		impl_opts.psk_identity = tcp_ctrlr->psk_identity;
	}
	opts.opts_size = sizeof(opts);
	spdk_sock_get_default_opts(&opts);
	opts.priority = ctrlr->trid.priority;
@@ -2156,6 +2158,16 @@ nvme_tcp_ctrlr_construct(const struct spdk_nvme_transport_id *trid,
	tctrlr->ctrlr.opts = *opts;
	tctrlr->ctrlr.trid = *trid;

	if (opts->psk[0] != '\0') {
		rc = nvme_tcp_generate_psk_identity(tctrlr->psk_identity, sizeof(tctrlr->psk_identity),
						    tctrlr->ctrlr.opts.hostnqn, tctrlr->ctrlr.trid.subnqn);
		if (rc) {
			SPDK_ERRLOG("could not generate PSK identity\n");
			free(tctrlr);
			return NULL;
		}
	}

	if (opts->transport_ack_timeout > NVME_TCP_CTRLR_MAX_TRANSPORT_ACK_TIMEOUT) {
		SPDK_NOTICELOG("transport_ack_timeout exceeds max value %d, use max value\n",
			       NVME_TCP_CTRLR_MAX_TRANSPORT_ACK_TIMEOUT);
+4 −7
Original line number Diff line number Diff line
@@ -3457,10 +3457,6 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
	struct tcp_subsystem_add_host_opts opts;
	struct spdk_nvmf_tcp_transport *ttransport;
	struct tcp_psk_entry *entry;
	/* This hardcoded PSK identity prefix will remain until
	 * support for different hash functions to generate PSK
	 * is introduced. */
	const char *psk_id_prefix = "NVMe0R01";
	char psk_identity[NVMF_PSK_IDENTITY_LEN];
	uint64_t key_len;
	int rc = 0;
@@ -3487,9 +3483,9 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,

	ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport);
	/* Generate PSK identity. */
	if (snprintf(psk_identity, NVMF_PSK_IDENTITY_LEN, "%s %s %s", psk_id_prefix, hostnqn,
		     subsystem->subnqn) < 0) {
		SPDK_ERRLOG("Could not construct PSK identity string!\n");
	rc = nvme_tcp_generate_psk_identity(psk_identity, NVMF_PSK_IDENTITY_LEN, hostnqn,
					    subsystem->subnqn);
	if (rc) {
		rc = -EINVAL;
		goto end;
	}
@@ -3507,6 +3503,7 @@ nvmf_tcp_subsystem_add_host(struct spdk_nvmf_transport *transport,
		rc = -ENOMEM;
		goto end;
	}

	if (snprintf(entry->hostnqn, sizeof(entry->hostnqn), "%s", hostnqn) < 0) {
		SPDK_ERRLOG("Could not write hostnqn string!\n");
		rc = -EINVAL;
Loading