xref: /spdk/test/nvmf/host/auth.sh (revision 83ba9086796471697a4975a58f60e2392bccd08c)
1#!/usr/bin/env bash
2# SPDX-License-Identifier: BSD-3-Clause
3# Copyright (C) 2023 Intel Corporation.  All rights reserved.
4#
5
6testdir=$(readlink -f "$(dirname "$0")")
7rootdir=$(readlink -f "$testdir/../../../")
8
9source "$rootdir/test/common/autotest_common.sh"
10source "$rootdir/test/nvmf/common.sh"
11
12# shellcheck disable=SC2190
13digests=("sha256" "sha384" "sha512")
14# There's a bug in the kernel with the way dhgroups are negotiated that makes it impossible to
15# select null dhgroup, so skip it for now.
16dhgroups=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192")
17subnqn="nqn.2024-02.io.spdk:cnode0"
18hostnqn="nqn.2024-02.io.spdk:host0"
19nvmet_subsys="/sys/kernel/config/nvmet/subsystems/$subnqn"
20nvmet_host="/sys/kernel/config/nvmet/hosts/$hostnqn"
21keys=() ckeys=()
22
23cleanup() {
24	nvmftestfini || :
25	rm "$nvmet_subsys/allowed_hosts/$hostnqn" || :
26	rmdir "$nvmet_host" || :
27	clean_kernel_target || :
28	rm -f "${keys[@]}" "$output_dir/nvme-auth.log"
29	# configure_kernel_target() binds the SSDs to the kernel driver, so move them back to
30	# userspace, as this is what the tests running after this one expect
31	"$rootdir/scripts/setup.sh"
32}
33
34nvmet_auth_init() {
35	configure_kernel_target "$subnqn" "$(get_main_ns_ip)"
36	mkdir "$nvmet_host"
37	echo 0 > "$nvmet_subsys/attr_allow_any_host"
38	ln -s "$nvmet_host" "$nvmet_subsys/allowed_hosts/$hostnqn"
39}
40
41nvmet_auth_set_key() {
42	local digest dhgroup keyid key ckey
43
44	digest="$1" dhgroup="$2" keyid="$3"
45	key=$(< "${keys[keyid]}")
46	ckey=${ckeys[keyid]:+$(< ${ckeys[keyid]})}
47
48	echo "hmac($digest)" > "$nvmet_host/dhchap_hash"
49	echo "$dhgroup" > "$nvmet_host/dhchap_dhgroup"
50	echo "$key" > "$nvmet_host/dhchap_key"
51	[[ -z "$ckey" ]] || echo "$ckey" > "$nvmet_host/dhchap_ctrl_key"
52}
53
54connect_authenticate() {
55	local digest dhgroup keyid ckey
56
57	digest="$1" dhgroup="$2" keyid="$3"
58	ckey=(${ckeys[keyid]:+--dhchap-ctrlr-key "ckey${keyid}"})
59
60	rpc_cmd bdev_nvme_set_options --dhchap-digests "$digest" --dhchap-dhgroups "$dhgroup"
61	rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
62		-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
63		--dhchap-key "key${keyid}" "${ckey[@]}"
64	[[ $(rpc_cmd bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]]
65	rpc_cmd bdev_nvme_detach_controller nvme0
66}
67
68nvmftestinit
69nvmfappstart -L nvme_auth &> "$output_dir/nvme-auth.log"
70trap "cat "$output_dir/nvme-auth.log"; cleanup" SIGINT SIGTERM EXIT
71
72# Set host/ctrlr key pairs with one combination w/o bidirectional authentication
73keys[0]=$(gen_dhchap_key "null" 32) ckeys[0]=$(gen_dhchap_key "sha512" 64)
74keys[1]=$(gen_dhchap_key "null" 48) ckeys[1]=$(gen_dhchap_key "sha384" 48)
75keys[2]=$(gen_dhchap_key "sha256" 32) ckeys[2]=$(gen_dhchap_key "sha256" 32)
76keys[3]=$(gen_dhchap_key "sha384" 48) ckeys[3]=$(gen_dhchap_key "null" 32)
77keys[4]=$(gen_dhchap_key "sha512" 64) ckeys[4]=""
78
79waitforlisten "$nvmfpid"
80for i in "${!keys[@]}"; do
81	rpc_cmd keyring_file_add_key "key$i" "${keys[i]}"
82	[[ -n "${ckeys[i]}" ]] && rpc_cmd keyring_file_add_key "ckey$i" "${ckeys[i]}"
83done
84
85nvmet_auth_init
86
87# Connect with all digests/dhgroups enabled
88nvmet_auth_set_key "sha256" "ffdhe2048" 1
89connect_authenticate \
90	"$(
91		IFS=,
92		printf "%s" "${digests[*]}"
93	)" \
94	"$(
95		IFS=,
96		printf "%s" "${dhgroups[*]}"
97	)" 1
98
99# Check all digest/dhgroup/key combinations
100for digest in "${digests[@]}"; do
101	for dhgroup in "${dhgroups[@]}"; do
102		for keyid in "${!keys[@]}"; do
103			nvmet_auth_set_key "$digest" "$dhgroup" "$keyid"
104			connect_authenticate "$digest" "$dhgroup" "$keyid"
105		done
106	done
107done
108
109# Ensure that a missing key results in failed attach
110nvmet_auth_set_key "sha256" "ffdhe2048" 1
111rpc_cmd bdev_nvme_set_options --dhchap-digests "sha256" --dhchap-dhgroups "ffdhe2048"
112NOT rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
113	-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn"
114(($(rpc_cmd bdev_nvme_get_controllers | jq 'length') == 0))
115
116# Check that mismatched keys result in failed attach
117NOT rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
118	-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
119	--dhchap-key "key2"
120(($(rpc_cmd bdev_nvme_get_controllers | jq 'length') == 0))
121
122# Check that a failed controller authentication results in failed attach
123NOT rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
124	-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
125	--dhchap-key "key1" --dhchap-ctrlr-key "ckey2"
126
127# Check reauthentication
128rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
129	-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
130	--dhchap-key "key1" --dhchap-ctrlr-key "ckey1" --ctrlr-loss-timeout-sec 1 \
131	--reconnect-delay-sec 1
132nvmet_auth_set_key "sha256" "ffdhe2048" 2
133rpc_cmd bdev_nvme_set_keys "nvme0" --dhchap-key "key2" --dhchap-ctrlr-key "ckey2"
134[[ $(rpc_cmd bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]]
135# Use wrong keys and verify that the ctrlr will get disconnected after ctrlr-loss-timeout-sec
136NOT rpc_cmd bdev_nvme_set_keys "nvme0" --dhchap-key "key1" --dhchap-ctrlr-key "ckey2"
137while (($(rpc_cmd bdev_nvme_get_controllers | jq 'length') != 0)); do
138	sleep 1s
139done
140# Do the same, but this time try with a valid host key, but bad ctrlr key
141nvmet_auth_set_key "sha256" "ffdhe2048" 1
142rpc_cmd bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
143	-a "$(get_main_ns_ip)" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
144	--dhchap-key "key1" --dhchap-ctrlr-key "ckey1" --ctrlr-loss-timeout-sec 1 \
145	--reconnect-delay-sec 1
146nvmet_auth_set_key "sha256" "ffdhe2048" 2
147NOT rpc_cmd bdev_nvme_set_keys "nvme0" --dhchap-key "key2" --dhchap-ctrlr-key "ckey1"
148while (($(rpc_cmd bdev_nvme_get_controllers | jq 'length') != 0)); do
149	sleep 1s
150done
151
152trap - SIGINT SIGTERM EXIT
153cleanup
154