Spdk/test/sma/crypto.sh
paul luse eb53c23236 add (c) and SPDX header to bash files as needed
per Intel policy to include file commit date using git cmd
below.  The policy does not apply to non-Intel (C) notices.

git log --follow -C90% --format=%ad --date default <file> | tail -1

and then pull just the year from the result.

Intel copyrights were not added to files where Intel either had
no contribution ot the contribution lacked substance (ie license
header updates, formatting changes, etc)

For intel copyrights added, --follow and -C95% were used.

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: I2ef86976095b88a9bf5b1003e59f3943cd6bbe4c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15209
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2022-11-29 08:27:51 +00:00

275 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (C) 2022 Intel Corporation
# All rights reserved.
#
testdir=$(readlink -f "$(dirname "$0")")
rootdir=$(readlink -f "$testdir/../..")
source "$rootdir/test/common/autotest_common.sh"
source "$testdir/common.sh"
rpc_py="$rootdir/scripts/rpc.py"
localnqn=nqn.2016-06.io.spdk:cnode0
tgtnqn=nqn.2016-06.io.spdk:tgt0
key0=1234567890abcdef1234567890abcdef
key1=deadbeefcafebabefeedbeefbabecafe
tgtsock=/var/tmp/spdk.sock2
discovery_port=8009
cleanup() {
killprocess $smapid
killprocess $hostpid
killprocess $tgtpid
}
gen_volume_params() {
local volume_id=$1 cipher=$2 key=$3 key2=$4 config
local -a params crypto
config=$(
cat <<- PARAMS
"volume_id": "$(uuid2base64 $volume_id)",
"nvmf": {
"hostnqn": "nqn.2016-06.io.spdk:host0",
"discovery": {
"discovery_endpoints": [
{
"trtype": "tcp",
"traddr": "127.0.0.1",
"trsvcid": "$discovery_port"
}
]
}
}
PARAMS
)
params+=("$config")
local IFS=","
if [[ -n "$cipher" ]]; then
crypto+=("\"cipher\": $(get_cipher $cipher)")
crypto+=("\"key\": \"$(format_key $key)\"")
if [[ -n "$key2" ]]; then
crypto+=("\"key2\": \"$(format_key $key2)\"")
fi
crypto_config=$(
cat <<- PARAMS
"crypto": {
${crypto[*]}
}
PARAMS
)
params+=("$crypto_config")
fi
cat <<- PARAMS
"volume": {
${params[*]}
}
PARAMS
}
create_device() {
"$rootdir/scripts/sma-client.py" <<- CREATE
{
"method": "CreateDevice",
"params": {
"nvmf_tcp": {
"subnqn": "$localnqn",
"adrfam": "ipv4",
"traddr": "127.0.0.1",
"trsvcid": "4420"
}
${1:+, $(gen_volume_params "$@")}
}
}
CREATE
}
delete_device() {
"$rootdir/scripts/sma-client.py" <<- DELETE
{
"method": "DeleteDevice",
"params": {
"handle": "$1"
}
}
DELETE
}
attach_volume() {
local device=$1
shift
"$rootdir/scripts/sma-client.py" <<- ATTACH
{
"method": "AttachVolume",
"params": {
"device_handle": "$device",
$(gen_volume_params "$@")
}
}
ATTACH
}
detach_volume() {
"$rootdir/scripts/sma-client.py" <<- DETACH
{
"method": "DetachVolume",
"params": {
"device_handle": "$1",
"volume_id": "$(uuid2base64 $2)"
}
}
DETACH
}
verify_crypto_volume() {
local nqn=$1 uuid=$2 ns ns_bdev
ns=$(rpc_cmd nvmf_get_subsystems $nqn | jq -r '.[0].namespaces[0]')
ns_bdev=$(jq -r '.name' <<< "$ns")
# Make sure that the namespace is a crypto bdev and that there's only a single crypto bdev
[[ $(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[0].product_name') == crypto ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 1 ]]
# Check that the namespace's UUID/NGUID matches the one requested by the user
[[ $(jq -r '.uuid' <<< "$ns") == "$uuid" ]]
[[ $(jq -r '.nguid' <<< "$ns") == "$(uuid2nguid $uuid)" ]]
}
trap "cleanup; exit 1" SIGINT SIGTERM EXIT
"$rootdir/build/bin/spdk_tgt" -m 0x1 &
hostpid=$!
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" -m 0x2 &
tgtpid=$!
$rootdir/scripts/sma.py -c <(
cat <<- CONFIG
address: 127.0.0.1
port: 8080
devices:
- name: 'nvmf_tcp'
crypto:
name: 'bdev_crypto'
params:
driver: 'crypto_aesni_mb'
CONFIG
) &
smapid=$!
# Wait until the SMA starts listening
sma_waitforlisten
# Prepare the target
uuid=$(uuidgen)
waitforlisten "$tgtpid" "$tgtsock"
$rpc_py -s "$tgtsock" << CONFIG
bdev_malloc_create -b malloc0 32 4096 -u $uuid
nvmf_create_transport -t tcp
nvmf_create_subsystem $tgtnqn -a
nvmf_subsystem_add_listener discovery -t tcp -a 127.0.0.1 -s $discovery_port
nvmf_subsystem_add_listener -t tcp -a 127.0.0.1 -s 4421 -f ipv4 $tgtnqn
nvmf_subsystem_add_ns $tgtnqn malloc0
CONFIG
# Create an empty device first
device=$(create_device | jq -r '.handle')
# First attach a volume without crypto
attach_volume $device $uuid
ns_bdev=$(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].name')
[[ $(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[0].product_name') == 'NVMe disk' ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 0 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].nguid') == "$(uuid2nguid $uuid)" ]]
detach_volume $device $uuid
# Now attach a volume with crypto enabled
attach_volume $device $uuid AES_CBC $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 1 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 1 ]]
# Make sure that the namespace exposed in the subsystem is a crypto bdev and is using malloc bdev's UUID
verify_crypto_volume $localnqn $uuid
# Check that it's using correct key
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev") == "$key0" ]]
# Attach the same volume again
attach_volume $device $uuid AES_CBC $key0
# Nothing should change
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 1 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 1 ]]
verify_crypto_volume $localnqn $uuid
crypto_bdev2=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
[[ $(jq -r '.name' <<< "$crypto_bdev") == $(jq -r '.name' <<< "$crypto_bdev2") ]]
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev2") == "$key0" ]]
# Try to do attach it again, but this time use a different crypto algorithm
NOT attach_volume $device $uuid AES_XTS $key0
# Check the same, this time changing the key
NOT attach_volume $device $uuid AES_CBC $key1
# Check the same, this time adding second key
NOT attach_volume $device $uuid AES_CBC $key0 $key1
# Check out-of-range cipher value
NOT attach_volume $device $uuid 8 $key0
# Make sure these failures haven't affected anything
verify_crypto_volume $localnqn $uuid
detach_volume $device $uuid
# Check that if there's something wrong with crypto params, the volume won't get attached and
# everything is cleaned up afterwards
NOT attach_volume $device $uuid 8 $key0
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 0 ]]
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
delete_device $device
# Check that it's possible to create a device immediately specyfing a volume with crypto
device=$(create_device $uuid AES_CBC $key0 | jq -r '.handle')
verify_crypto_volume $localnqn $uuid
delete_device $device
# Try to create a device with incorrect volume crypto params, check that it fails and everything
# is cleaned up afterwards
NOT create_device $uuid 8 $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
[[ $(rpc_cmd nvmf_get_subsystems | jq -r "[.[] | select(.nqn == \"$localnqn\")] | length") -eq 0 ]]
# Check that if crypto is disabled, it's not possible to attach a volume with crypto
killprocess $smapid
$rootdir/scripts/sma.py -c <(
cat <<- CONFIG
address: 127.0.0.1
port: 8080
devices:
- name: 'nvmf_tcp'
CONFIG
) &
smapid=$!
sma_waitforlisten
device=$(create_device | jq -r '.handle')
NOT attach_volume $device $uuid AES_CBC $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
cleanup
trap - SIGINT SIGTERM EXIT