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

nvme: initial in-band authentication code



This patch adds structures that will be used to implement NVMe in-band
authentication using the DH-HMAC-CHAP protocol.  They're mostly empty for
now, the following patches will implement each step of this process.

The authentication is executed by exchanging several messages using the
AUTHENTICATION_SEND and AUTHENTICATION_RECEIVE commands from the Fabrics
Command Set.  The messages sent by the host map to the SEND commands,
while those sent by the controller map to the RECEIVE commands.

The flow roughly consists of 5 steps:
 1. The host sends a AUTH_negotiate message to listing the hash function
    and Diffie-Hellman group it supports.
 2. The controller responds with a DH-HMAC-CHAP_challenge message
    selecting one of the hash functions and DH groups from those sent by
    the host along with a challenge value and an optional DH public key.
 3. The host calculates an HMAC of the challenge (optionally augmented
    with a DH secret) and sends it back to the controller using a
    DH-HMAC-CHAP_reply message along with its DH public key.  If
    bidirectional authentication is requested, it includes its own
    challenge value in that message.
 4. The controller verifies the response to the challenge received from
    the host comparing it to its HMAC calculation.  If successful, it
    sends a DH-HMAC-CHAP_success1 message with an optional response to
    the host challenge.
 5. If bidirectional authentication wasn't requested, the authentication
    process is finished at this point.  Otherwise the host verifies
    controller's response to the host's challenge and, if successful,
    sends a DH-HMAC-CHAP_success2 message.

Any errors during this process are reported by sending either an
AUTH_failure1 message (sent by the controller) or AUTH_failure2 (sent by
the host).

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


Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 53ba4f62
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -218,6 +218,9 @@ CONFIG_HAVE_EXECINFO_H=n
# libkeytuils is available
CONFIG_HAVE_KEYUTILS=n

# OpenSSL has EVP_MAC definitions
CONFIG_HAVE_EVP_MAC=n

# Path to IPSEC_MB used by DPDK
CONFIG_IPSEC_MB_DIR=

+8 −0
Original line number Diff line number Diff line
@@ -701,6 +701,9 @@ else
fi
BUILD_CMD+=(-I/usr/local/include -L/usr/local/lib)
BUILD_CMD+=("-fuse-ld=$LD_TYPE")
if [[ -n "${CONFIG[OPENSSL_PATH]}" ]]; then
	BUILD_CMD+=("-I${CONFIG[OPENSSL_PATH]}/include" "-L${CONFIG[OPENSSL_PATH]}")
fi

if [[ "${CONFIG[VFIO_USER]}" = "y" ]]; then
	if ! echo -e '#include <json-c/json.h>' \
@@ -1128,6 +1131,11 @@ if echo -e '#include <keyutils.h>\nint main(void) { request_key(0, 0, 0, -1); re
	CONFIG[HAVE_KEYUTILS]=y
fi

if echo -e '#include <openssl/evp.h>\nint main(void) { EVP_MAC *m = EVP_MAC_fetch(0, 0, 0); return 0; }' \
	| "${BUILD_CMD[@]}" - -lcrypto 2> /dev/null; then
	CONFIG[HAVE_EVP_MAC]=y
fi

if [[ "${CONFIG[OCF]}" = "y" ]]; then
	# If OCF_PATH is a file, assume it is a library and use it to compile with
	if [ -f ${CONFIG[OCF_PATH]} ]; then
+6 −1
Original line number Diff line number Diff line
@@ -290,8 +290,13 @@ struct spdk_nvme_ctrlr_opts {
	 * Pre-shared key for NVMe/TCP's TLS connection.
	 */
	struct spdk_key *tls_psk;

	/**
	 * In-band authentication DH-HMAC-CHAP key.
	 */
	struct spdk_key *dhchap_key;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_opts) == 832, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_opts) == 840, "Incorrect size");

/**
 * NVMe acceleration operation callback.
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_fabric.c nvme_ns_cmd.c \
C_SRCS-$(CONFIG_NVME_CUSE) += nvme_cuse.c
C_SRCS-$(CONFIG_VFIO_USER) += nvme_vfio_user.c
C_SRCS-$(CONFIG_RDMA) += nvme_rdma.c
C_SRCS-$(CONFIG_HAVE_EVP_MAC) += nvme_auth.c

LIBNAME = nvme
LOCAL_SYS_LIBS =
+1 −0
Original line number Diff line number Diff line
@@ -970,6 +970,7 @@ nvme_ctrlr_opts_init(struct spdk_nvme_ctrlr_opts *opts,
	SET_FIELD(disable_read_changed_ns_list_log_page);
	SET_FIELD_ARRAY(psk);
	SET_FIELD(tls_psk);
	SET_FIELD(dhchap_key);

#undef FIELD_OK
#undef SET_FIELD
Loading