xref: /spdk/test/nvmf/fips/fips.sh (revision d341bee70b3ec097a3aeefc67adc273015511929)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2023 Intel Corporation
4#  All rights reserved.
5#
6
7testdir="$(readlink -f $(dirname $0))"
8rootdir="$(readlink -f $testdir/../../..)"
9
10source "$rootdir/test/common/autotest_common.sh"
11source "$rootdir/test/nvmf/common.sh"
12rpc_py="$rootdir/scripts/rpc.py"
13
14cleanup() {
15	process_shm --id $NVMF_APP_SHM_ID || true
16	killprocess $bdevperf_pid
17	nvmftestfini || true
18	rm -f $key_path
19}
20
21setup_nvmf_tgt_conf() {
22	local key=$1
23
24	$rpc_py <<- EOF
25		nvmf_create_transport $NVMF_TRANSPORT_OPTS
26		nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -s SPDK00000000000001 -m 10
27		nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t $TEST_TRANSPORT \
28		-a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -k
29		bdev_malloc_create 32 4096 -b malloc0
30		nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 malloc0 -n 1
31		keyring_file_add_key key0 "$key"
32		nvmf_subsystem_add_host nqn.2016-06.io.spdk:cnode1 nqn.2016-06.io.spdk:host1 \
33			--psk key0
34	EOF
35}
36
37build_openssl_config() {
38	cat <<- NO_DEFAULT
39		openssl_conf = openssl_spdk
40
41		[openssl_spdk]
42		providers = provider_sect_spdk
43		alg_section = algorithm_sect_spdk
44
45		[provider_sect_spdk]
46		fips = fips_sect_spdk
47		base = base_sect_spdk
48
49		[base_sect_spdk]
50		activate = 1
51
52		[fips_sect_spdk]
53		activate = 1
54
55		[algorithm_sect_spdk]
56		default_properties = fips=yes
57	NO_DEFAULT
58	if [[ ! -t 0 ]]; then
59		cat -
60	fi
61}
62
63build_openssl_config_fallback() {
64	build_openssl_config <<- FIPS
65		$(openssl fipsinstall -module "$(openssl info -modulesdir)/fips.so" 2> /dev/null)
66
67		[openssl_spdk]
68		providers = provider_sect_spdk
69		alg_section = algorithm_sect_spdk
70
71		[provider_sect_spdk]
72		fips = fips_sect
73		base = base_sect_spdk
74
75		[base_sect_spdk]
76		activate = 1
77
78		[algorithm_sect_spdk]
79		default_properties = fips=yes
80	FIPS
81}
82
83check_openssl_version() {
84	local target=${1:-3.0.0}
85
86	ge "$(openssl version | awk '{print $2}')" "$target"
87}
88
89# Ensure environment is prepared for running this test.
90if ! check_openssl_version; then
91	echo "Unsupported OpenSSL version"
92	exit 1
93fi
94
95# Absence of this library means that OpenSSL was configured and built without FIPS support.
96if [[ ! -f "$(openssl info -modulesdir)/fips.so" ]]; then
97	echo "FIPS library not found"
98	exit 1
99fi
100
101if ! warn=$(openssl fipsinstall -help 2>&1); then
102	if [[ $warn == "This command is not enabled"* ]]; then
103		# Rhel-based openssl >=3.0.9 builds no longer support fipsinstall command.
104		# Enforce proper patches.
105		export callback=build_openssl_config
106	else
107		exit 1
108	fi
109else
110	# We need to explicitly enable FIPS via proper config.
111	export callback=build_openssl_config_fallback
112fi
113
114"$callback" > spdk_fips.conf
115export OPENSSL_CONF=spdk_fips.conf
116
117mapfile -t providers < <(openssl list -providers | grep "name")
118# We expect OpenSSL to present the providers we requested. If OpenSSL loaded other providers
119# (e.g. "default") or was unable to load "base" and "fips", the following line will fail,
120# indicating that OPENSSL_CONF is invalid or OpenSSL itself is malconfigured.
121if ((${#providers[@]} != 2)) || [[ ${providers[0],,} != *base* || ${providers[1],,} != *fips* ]]; then
122	printf 'We expected Base and FIPS providers, got:\n'
123	printf '  %s\n' "${providers[@]:-no providers}"
124	exit 1
125fi
126
127# MD5 is not FIPS compliant, so below command should fail in FIPS-only environment.
128NOT openssl md5 <(:)
129
130# Start NVMf TLS test.
131nvmftestinit
132nvmfappstart -m 0x2
133
134trap 'cleanup' EXIT
135
136# Key taken from NVM Express TCP Transport Specification 1.0c.
137key="NVMeTLSkey-1:01:VRLbtnN9AQb2WXW3c9+wEf/DRLz0QuLdbYvEhwtdWwNf9LrZ:"
138key_path="$(mktemp -t "spdk-psk.XXX")"
139echo -n "$key" > $key_path
140chmod 0600 $key_path
141
142setup_nvmf_tgt_conf $key_path
143
144# Use bdevperf as initiator.
145bdevperf_rpc_sock="/var/tmp/bdevperf.sock"
146"$rootdir/build/examples/bdevperf" -m 0x4 -z -r $bdevperf_rpc_sock \
147	-q 128 -o 4096 -w verify -t 10 &
148bdevperf_pid=$!
149waitforlisten $bdevperf_pid $bdevperf_rpc_sock
150
151$rpc_py -s $bdevperf_rpc_sock keyring_file_add_key key0 "$key_path"
152$rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b TLSTEST -t $TEST_TRANSPORT \
153	-a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -f ipv4 -n nqn.2016-06.io.spdk:cnode1 \
154	-q nqn.2016-06.io.spdk:host1 --psk key0
155
156"$rootdir/examples/bdev/bdevperf/bdevperf.py" -s $bdevperf_rpc_sock perform_tests
157