1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (c) 2024 Intel Corporation 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") 14dhgroups=("null" "ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") 15subnqn="nqn.2024-03.io.spdk:cnode0" 16hostnqn="$NVME_HOSTNQN" 17hostsock="/var/tmp/host.sock" 18keys=() ckeys=() 19 20cleanup() { 21 killprocess $hostpid || : 22 nvmftestfini || : 23 rm -f "${keys[@]}" "${ckeys[@]}" "$output_dir"/nvm{e,f}-auth.log 24} 25 26dumplogs() { 27 cat "$output_dir/nvme-auth.log" 28 cat "$output_dir/nvmf-auth.log" 29} 30 31hostrpc() { "$rootdir/scripts/rpc.py" -s "$hostsock" "$@"; } 32 33nvme_connect() { 34 # Force 1 I/O queue to speed up the connection 35 nvme connect -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" -n "$subnqn" -i 1 \ 36 -q "$hostnqn" --hostid "$NVME_HOSTID" "$@" 37} 38 39bdev_connect() { 40 hostrpc bdev_nvme_attach_controller -t "$TEST_TRANSPORT" -f ipv4 \ 41 -a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" "$@" 42} 43 44connect_authenticate() { 45 local digest dhgroup key ckey qpairs 46 47 digest="$1" dhgroup="$2" key="key$3" 48 ckey=(${ckeys[$3]:+--dhchap-ctrlr-key "ckey$3"}) 49 50 rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "$key" "${ckey[@]}" 51 bdev_connect -b "nvme0" --dhchap-key "$key" "${ckey[@]}" 52 53 [[ $(hostrpc bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]] 54 qpairs=$(rpc_cmd nvmf_subsystem_get_qpairs "$subnqn") 55 [[ $(jq -r ".[0].auth.digest" <<< "$qpairs") == "$digest" ]] 56 [[ $(jq -r ".[0].auth.dhgroup" <<< "$qpairs") == "$dhgroup" ]] 57 [[ $(jq -r ".[0].auth.state" <<< "$qpairs") == "completed" ]] 58 hostrpc bdev_nvme_detach_controller nvme0 59 60 nvme_connect --dhchap-secret "$(< "${keys[$3]}")" \ 61 ${ckeys[$3]:+--dhchap-ctrl-secret "$(< "${ckeys[$3]}")"} 62 nvme disconnect -n "$subnqn" 63 rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn" 64} 65 66nvmftestinit 67nvmfappstart -L nvmf_auth &> "$output_dir/nvmf-auth.log" 68"$rootdir/build/bin/spdk_tgt" -m 2 -r "$hostsock" -L nvme_auth &> "$output_dir/nvme-auth.log" & 69hostpid=$! 70 71trap "dumplogs; cleanup" SIGINT SIGTERM EXIT 72 73# Set host/ctrlr key pairs with one combination w/o bidirectional authentication 74keys[0]=$(gen_dhchap_key "null" 48) ckeys[0]=$(gen_dhchap_key "sha512" 64) 75keys[1]=$(gen_dhchap_key "sha256" 32) ckeys[1]=$(gen_dhchap_key "sha384" 48) 76keys[2]=$(gen_dhchap_key "sha384" 48) ckeys[2]=$(gen_dhchap_key "sha256" 32) 77keys[3]=$(gen_dhchap_key "sha512" 64) ckeys[3]="" 78 79waitforlisten "$nvmfpid" 80waitforlisten "$hostpid" "$hostsock" 81rpc_cmd <<- CONFIG 82 nvmf_create_transport -t "$TEST_TRANSPORT" 83 nvmf_create_subsystem "$subnqn" 84 nvmf_subsystem_add_listener -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" \ 85 -s "$NVMF_PORT" "$subnqn" 86CONFIG 87 88for i in "${!keys[@]}"; do 89 rpc_cmd keyring_file_add_key "key$i" "${keys[i]}" 90 hostrpc keyring_file_add_key "key$i" "${keys[i]}" 91 if [[ -n "${ckeys[i]}" ]]; then 92 rpc_cmd keyring_file_add_key "ckey$i" "${ckeys[i]}" 93 hostrpc keyring_file_add_key "ckey$i" "${ckeys[i]}" 94 fi 95done 96 97# Check all digest/dhgroup/key combinations 98for digest in "${digests[@]}"; do 99 for dhgroup in "${dhgroups[@]}"; do 100 for keyid in "${!keys[@]}"; do 101 hostrpc bdev_nvme_set_options --dhchap-digests "$digest" \ 102 --dhchap-dhgroups "$dhgroup" 103 connect_authenticate "$digest" "$dhgroup" $keyid 104 done 105 done 106done 107 108# Connect with all digests/dhgroups enabled 109hostrpc bdev_nvme_set_options \ 110 --dhchap-digests \ 111 "$( 112 IFS=, 113 printf "%s" "${digests[*]}" 114 )" \ 115 --dhchap-dhgroups \ 116 "$( 117 IFS=, 118 printf "%s" "${dhgroups[*]}" 119 )" 120# The target should select the strongest digest/dhgroup 121connect_authenticate "${digests[-1]}" "${dhgroups[-1]}" 0 122 123# Check that mismatched keys result in failed attach 124rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1" 125NOT bdev_connect -b "nvme0" --dhchap-key "key2" 126rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn" 127 128# Check that mismatched controller keys result in failed attach 129rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1" --dhchap-ctrlr-key "ckey1" 130NOT bdev_connect -b "nvme0" --dhchap-key "key1" --dhchap-ctrlr-key "ckey2" 131rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn" 132 133# Check that a missing controller key results in a failed attach 134rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1" 135NOT bdev_connect -b "nvme0" --dhchap-key "key1" --dhchap-ctrlr-key "ckey1" 136rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn" 137 138# Limit allowed digests/dhgroups on the target 139killprocess "$nvmfpid" 140nvmfappstart --wait-for-rpc -L nvmf_auth &>> "$output_dir/nvmf-auth.log" 141trap "dumplogs; cleanup" SIGINT SIGTERM EXIT 142 143waitforlisten "$nvmfpid" 144rpc_cmd <<- CONFIG 145 nvmf_set_config --dhchap-digests sha384,sha512 --dhchap-dhgroups ffdhe6144,ffdhe8192 146 framework_start_init 147 nvmf_create_transport -t "$TEST_TRANSPORT" 148 nvmf_create_subsystem "$subnqn" 149 nvmf_subsystem_add_listener -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" \ 150 -s "$NVMF_PORT" "$subnqn" 151 keyring_file_add_key key3 "${keys[3]}" 152CONFIG 153 154connect_authenticate "sha512" "ffdhe8192" 3 155 156# Check that authentication fails when no common digests are allowed 157rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key key3 158hostrpc bdev_nvme_set_options --dhchap-digests "sha256" 159NOT bdev_connect -b "nvme0" --dhchap-key "key3" 160 161# Check that authentication fails when no common dhgroups are allowed 162hostrpc bdev_nvme_set_options --dhchap-dhgroups "ffdhe2048" \ 163 --dhchap-digests \ 164 "$( 165 IFS=, 166 printf "%s" "${digests[*]}" 167 )" 168NOT bdev_connect -b "nvme0" --dhchap-key "key3" 169 170# Check that the authentication fails when the host wants to authenticate the target (i.e. user set 171# the dhchap_ctrlr_key), but the target doesn't require authentication 172hostrpc bdev_nvme_set_options \ 173 --dhchap-digests \ 174 "$( 175 IFS=, 176 printf "%s" "${digests[*]}" 177 )" \ 178 --dhchap-dhgroups \ 179 "$( 180 IFS=, 181 printf "%s" "${dhgroups[*]}" 182 )" 183rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn" 184rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" 185NOT bdev_connect -b "nvme0" --dhchap-key "key0" --dhchap-ctrlr-key "key1" 186 187# But it's fine when the host key is set and the controller key is not 188bdev_connect -b "nvme0" --dhchap-key "key0" 189[[ $(hostrpc bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]] 190hostrpc bdev_nvme_detach_controller nvme0 191 192trap - SIGINT SIGTERM EXIT 193cleanup 194