bdev/crypto: Use accel framework
All DPDK related code is removed, handling of RESET command was sligthly updated. Handling of -ENOMEM was updated for cases when accel API returns -ENOMEM Crypto tests in blockdev.sh were extended with more crypto_bdevs to verify NOMEM cases - that failed with original vbdev_crypto implementation Signed-off-by: Alexey Marchuk <alexeymar@nvidia.com> Change-Id: If1feba2449bee852c6c4daca4b3406414db6fded Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14860 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
c1e9ed6d4c
commit
13f97e6737
@ -23,6 +23,8 @@ Protection information is now supported by the malloc bdev module.
|
|||||||
|
|
||||||
A new API `spkd_bdev_part_submit_request_ext` was added to specify a custom completion callback.
|
A new API `spkd_bdev_part_submit_request_ext` was added to specify a custom completion callback.
|
||||||
|
|
||||||
|
vbdev_crypto is updated to use accel framework instead of DPDK PMDs.
|
||||||
|
|
||||||
### scheduler
|
### scheduler
|
||||||
|
|
||||||
Changing scheduler from dynamic back to static is no longer possible,
|
Changing scheduler from dynamic back to static is no longer possible,
|
||||||
|
@ -335,6 +335,7 @@ if [ $SPDK_RUN_FUNCTIONAL_TEST -eq 1 ]; then
|
|||||||
|
|
||||||
if [ $SPDK_TEST_CRYPTO -eq 1 ]; then
|
if [ $SPDK_TEST_CRYPTO -eq 1 ]; then
|
||||||
run_test "blockdev_crypto_aesni" ./test/bdev/blockdev.sh "crypto_aesni"
|
run_test "blockdev_crypto_aesni" ./test/bdev/blockdev.sh "crypto_aesni"
|
||||||
|
run_test "blockdev_crypto_sw" ./test/bdev/blockdev.sh "crypto_sw"
|
||||||
# Proceed with the test only if QAT devices are in place
|
# Proceed with the test only if QAT devices are in place
|
||||||
if [[ $(lspci -d:37c8) ]]; then
|
if [[ $(lspci -d:37c8) ]]; then
|
||||||
run_test "blockdev_crypto_qat" ./test/bdev/blockdev.sh "crypto_qat"
|
run_test "blockdev_crypto_qat" ./test/bdev/blockdev.sh "crypto_qat"
|
||||||
|
76
doc/bdev.md
76
doc/bdev.md
@ -162,12 +162,23 @@ all volumes, if used it will return the name or an error that the device does no
|
|||||||
## Crypto Virtual Bdev Module {#bdev_config_crypto}
|
## Crypto Virtual Bdev Module {#bdev_config_crypto}
|
||||||
|
|
||||||
The crypto virtual bdev module can be configured to provide at rest data encryption
|
The crypto virtual bdev module can be configured to provide at rest data encryption
|
||||||
for any underlying bdev. The module relies on the DPDK CryptoDev Framework to provide
|
for any underlying bdev. The module relies on the SPDK Accel Framework to provide
|
||||||
all cryptographic functionality. The framework provides support for many different software
|
all cryptographic functionality.
|
||||||
only cryptographic modules as well hardware assisted support for the Intel QAT board and
|
One of the accel modules, dpdk_cryptodev is implemented with the DPDK CryptoDev API,
|
||||||
NVIDIA crypto enabled NICs.
|
it provides support for many different software only cryptographic modules as well hardware
|
||||||
The framework also provides support for cipher, hash, authentication and AEAD functions.
|
assisted support for the Intel QAT board and NVIDIA crypto enabled NICs.
|
||||||
At this time the SPDK virtual bdev module supports cipher only as follows:
|
|
||||||
|
For reads, the buffer provided to the crypto block device will be used as the destination buffer
|
||||||
|
for unencrypted data. For writes, however, a temporary scratch buffer is used as the
|
||||||
|
destination buffer for encryption which is then passed on to the underlying bdev as the
|
||||||
|
write buffer. This is done to avoid encrypting the data in the original source buffer which
|
||||||
|
may cause problems in some use cases.
|
||||||
|
|
||||||
|
Below is information about accel modules which support crypto operations:
|
||||||
|
|
||||||
|
### dpdk_cryptodev accel module
|
||||||
|
|
||||||
|
Supports the following ciphers:
|
||||||
|
|
||||||
- AESN-NI Multi Buffer Crypto Poll Mode Driver: RTE_CRYPTO_CIPHER_AES128_CBC
|
- AESN-NI Multi Buffer Crypto Poll Mode Driver: RTE_CRYPTO_CIPHER_AES128_CBC
|
||||||
- Intel(R) QuickAssist (QAT) Crypto Poll Mode Driver: RTE_CRYPTO_CIPHER_AES128_CBC,
|
- Intel(R) QuickAssist (QAT) Crypto Poll Mode Driver: RTE_CRYPTO_CIPHER_AES128_CBC,
|
||||||
@ -181,38 +192,61 @@ the crypto module break up all I/O into crypto operations of a size equal to the
|
|||||||
size of the underlying bdev. For example, a 4K I/O to a bdev with a 512B block size,
|
size of the underlying bdev. For example, a 4K I/O to a bdev with a 512B block size,
|
||||||
would result in 8 cryptographic operations.
|
would result in 8 cryptographic operations.
|
||||||
|
|
||||||
For reads, the buffer provided to the crypto module will be used as the destination buffer
|
### SW accel module
|
||||||
for unencrypted data. For writes, however, a temporary scratch buffer is used as the
|
|
||||||
destination buffer for encryption which is then passed on to the underlying bdev as the
|
|
||||||
write buffer. This is done to avoid encrypting the data in the original source buffer which
|
|
||||||
may cause problems in some use cases.
|
|
||||||
|
|
||||||
Example command
|
Supports the following ciphers:
|
||||||
|
|
||||||
`rpc.py bdev_crypto_create NVMe1n1 CryNvmeA crypto_aesni_mb 01234567891234560123456789123456`
|
- AES_XTS cipher with 128 or 256 bit keys implemented with ISA-L_crypto
|
||||||
|
|
||||||
This command will create a crypto vbdev called 'CryNvmeA' on top of the NVMe bdev
|
### General workflow
|
||||||
'NVMe1n1' and will use the DPDK software driver 'crypto_aesni_mb' and the key
|
|
||||||
'01234567891234560123456789123456'.
|
- Set desired accel module to perform crypto operations, that can be done with `accel_assign_opc` RPC command
|
||||||
|
- Create a named crypto key using `accel_crypto_key_create` RPC command. The key will use the assigned accel
|
||||||
|
module. Set of parameters and supported ciphers may be different in each accel module.
|
||||||
|
- Create virtual crypto block device providing the base block device name and the crypto key name
|
||||||
|
using `bdev_crypto_create` RPC command
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
Example command which uses dpdk_cryptodev accel module
|
||||||
|
```
|
||||||
|
# start SPDK application with `--wait-for-rpc` parameter
|
||||||
|
rpc.py dpdk_cryptodev_scan_accel_module
|
||||||
|
rpc.py dpdk_cryptodev_set_driver crypto_aesni_mb
|
||||||
|
rpc.py accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
rpc.py accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
rpc.py framework_start_init
|
||||||
|
rpc.py accel_crypto_key_create -c AES_CBC -k 01234567891234560123456789123456 -n key_aesni_cbc_1
|
||||||
|
rpc.py bdev_crypto_create NVMe1n1 CryNvmeA -n key_aesni_cbc_1
|
||||||
|
```
|
||||||
|
|
||||||
|
These commands will create a crypto vbdev called 'CryNvmeA' on top of the NVMe bdev
|
||||||
|
'NVMe1n1' and will use a key named `key_aesni_cbc_1`. The key will work with the accel module which
|
||||||
|
has been assigned for encrypt operations, in this example it will be the dpdk_cryptodev.
|
||||||
|
|
||||||
|
### Crypto key format
|
||||||
|
|
||||||
Please make sure the keys are provided in hexlified format. This means string passed to
|
Please make sure the keys are provided in hexlified format. This means string passed to
|
||||||
rpc.py must be twice as long than the key length in binary form.
|
rpc.py must be twice as long than the key length in binary form.
|
||||||
|
|
||||||
Example command
|
#### Example command
|
||||||
|
|
||||||
`rpc.py bdev_crypto_create -c AES_XTS -k2 7859243a027411e581e0c40a35c8228f NVMe1n1 CryNvmeA mlx5_pci d16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b09`
|
`rpc.py accel_crypto_key_create -c AES_XTS -k2 7859243a027411e581e0c40a35c8228f -k d16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b09 -n sample_key`
|
||||||
|
|
||||||
This command will create a crypto vbdev called 'CryNvmeA' on top of the NVMe bdev
|
This command will create a key called `sample_key`, the AES key
|
||||||
'NVMe1n1' and will use the DPDK software driver 'mlx5_pci', the AES key
|
|
||||||
'd16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b09' and the XTS key
|
'd16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b09' and the XTS key
|
||||||
'7859243a027411e581e0c40a35c8228f'. In other words, the compound AES_XTS key to be used is
|
'7859243a027411e581e0c40a35c8228f'. In other words, the compound AES_XTS key to be used is
|
||||||
'd16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b097859243a027411e581e0c40a35c8228f'
|
'd16a2f3a9e9f5b32daefacd7f5984f4578add84425be4a0baa489b9de8884b097859243a027411e581e0c40a35c8228f'
|
||||||
|
|
||||||
|
### Delete the virtual crypto block device
|
||||||
|
|
||||||
To remove the vbdev use the bdev_crypto_delete command.
|
To remove the vbdev use the bdev_crypto_delete command.
|
||||||
|
|
||||||
`rpc.py bdev_crypto_delete CryNvmeA`
|
`rpc.py bdev_crypto_delete CryNvmeA`
|
||||||
|
|
||||||
The MLX5 driver works with crypto enabled Nvidia NICs and requires special configuration of
|
### dpdk_cryptodev mlx5_pci driver configuration
|
||||||
|
|
||||||
|
The mlx5_pci driver works with crypto enabled Nvidia NICs and requires special configuration of
|
||||||
DPDK environment to enable crypto function. It can be done via SPDK event library by configuring
|
DPDK environment to enable crypto function. It can be done via SPDK event library by configuring
|
||||||
`env_context` member of `spdk_app_opts` structure or by passing corresponding CLI arguments in
|
`env_context` member of `spdk_app_opts` structure or by passing corresponding CLI arguments in
|
||||||
the following form: `--allow=BDF,class=crypto,wcs_file=/full/path/to/wrapped/credentials`, e.g.
|
the following form: `--allow=BDF,class=crypto,wcs_file=/full/path/to/wrapped/credentials`, e.g.
|
||||||
|
@ -443,6 +443,7 @@ Example response:
|
|||||||
"spdk_kill_instance",
|
"spdk_kill_instance",
|
||||||
"accel_get_opc_assignments",
|
"accel_get_opc_assignments",
|
||||||
"accel_crypto_key_create",
|
"accel_crypto_key_create",
|
||||||
|
"accel_crypto_key_destroy",
|
||||||
"accel_crypto_keys_get",
|
"accel_crypto_keys_get",
|
||||||
"ioat_scan_accel_module",
|
"ioat_scan_accel_module",
|
||||||
"dsa_scan_accel_module",
|
"dsa_scan_accel_module",
|
||||||
@ -1783,7 +1784,7 @@ Example response:
|
|||||||
|
|
||||||
### accel_crypto_key_create {#rpc_accel_crypto_key_create}
|
### accel_crypto_key_create {#rpc_accel_crypto_key_create}
|
||||||
|
|
||||||
Create a crypt key which will be used in accel framework
|
Create a crypto key which will be used in accel framework
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
@ -1822,6 +1823,41 @@ Example response:
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
### accel_crypto_key_destroy {#rpc_accel_crypto_key_destroy}
|
||||||
|
|
||||||
|
Destroy a crypto key. The user is responsible for ensuring that the deleted key is not used by acceleration modules.
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
Name | Optional | Type | Description
|
||||||
|
-----------|----------| ----------- | -----------------
|
||||||
|
name | Required | string | The key name
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
~~~json
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "accel_crypto_key_destroy",
|
||||||
|
"id": 1,
|
||||||
|
"params": {
|
||||||
|
"name": "super_key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
~~~json
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"result": true
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
### accel_crypto_keys_get {#rpc_accel_crypto_keys_get}
|
### accel_crypto_keys_get {#rpc_accel_crypto_keys_get}
|
||||||
|
|
||||||
Get information about existing crypto keys
|
Get information about existing crypto keys
|
||||||
@ -2039,7 +2075,7 @@ Set the DPDK cryptodev driver
|
|||||||
|
|
||||||
Name | Optional | Type | Description
|
Name | Optional | Type | Description
|
||||||
----------------------- |----------|--------| -----------
|
----------------------- |----------|--------| -----------
|
||||||
driver_name | Required | string | The driver, can be one of crypto_aesni_mb, crypto_qat or mlx5_pci
|
crypto_pmd | Required | string | The driver, can be one of crypto_aesni_mb, crypto_qat or mlx5_pci
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
@ -2051,7 +2087,7 @@ Example request:
|
|||||||
"method": "dpdk_cryptodev_set_driver",
|
"method": "dpdk_cryptodev_set_driver",
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"params": {
|
"params": {
|
||||||
"driver_name": "crypto_aesni_mb"
|
"crypto_pmd": "crypto_aesni_mb"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
@ -2693,13 +2729,15 @@ Create a new crypto bdev on a given base bdev.
|
|||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
Name | Optional | Type | Description
|
Name | Optional | Type | Description
|
||||||
----------------------- | -------- | ----------- | -----------
|
----------------------- |----------| ----------- | -----------
|
||||||
base_bdev_name | Required | string | Name of the base bdev
|
base_bdev_name | Required | string | Name of the base bdev
|
||||||
name | Required | string | Name of the crypto vbdev to create
|
name | Required | string | Name of the crypto vbdev to create
|
||||||
crypto_pmd | Required | string | Name of the crypto device driver
|
crypto_pmd | Optional | string | Name of the crypto device driver. Obsolete, see accel_crypto_key_create
|
||||||
key | Required | string | Key in hex form
|
key | Optional | string | Key in hex form. Obsolete, see accel_crypto_key_create
|
||||||
cipher | Required | string | Cipher to use, AES_CBC or AES_XTS (QAT and MLX5)
|
cipher | Optional | string | Cipher to use, AES_CBC or AES_XTS (QAT and MLX5). Obsolete, see accel_crypto_key_create
|
||||||
key2 | Required | string | 2nd key in hex form only required for cipher AES_XTS
|
key2 | Optional | string | 2nd key in hex form only required for cipher AET_XTS. Obsolete, see accel_crypto_key_create
|
||||||
|
key_name | Optional | string | Name of the key created with accel_crypto_key_create
|
||||||
|
module | Optional | string | Name of the accel module which is used to create a key (if no key_name specified)
|
||||||
|
|
||||||
Both key and key2 must be passed in the hexlified form. For example, 256bit AES key may look like this:
|
Both key and key2 must be passed in the hexlified form. For example, 256bit AES key may look like this:
|
||||||
afd9477abf50254219ccb75965fbe39f23ebead5676e292582a0a67f66b88215
|
afd9477abf50254219ccb75965fbe39f23ebead5676e292582a0a67f66b88215
|
||||||
|
@ -230,7 +230,7 @@ struct rpc_accel_crypto_keys_get_ctx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = {
|
static const struct spdk_json_object_decoder rpc_accel_crypto_keys_get_decoders[] = {
|
||||||
{"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true},
|
{"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -272,3 +272,44 @@ rpc_accel_crypto_keys_get(struct spdk_jsonrpc_request *request,
|
|||||||
spdk_jsonrpc_end_result(request, w);
|
spdk_jsonrpc_end_result(request, w);
|
||||||
}
|
}
|
||||||
SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME)
|
SPDK_RPC_REGISTER("accel_crypto_keys_get", rpc_accel_crypto_keys_get, SPDK_RPC_RUNTIME)
|
||||||
|
|
||||||
|
static const struct spdk_json_object_decoder rpc_accel_crypto_key_destroy_decoders[] = {
|
||||||
|
{"key_name", offsetof(struct rpc_accel_crypto_keys_get_ctx, key_name), spdk_json_decode_string, true},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_accel_crypto_key_destroy(struct spdk_jsonrpc_request *request,
|
||||||
|
const struct spdk_json_val *params)
|
||||||
|
{
|
||||||
|
struct rpc_accel_crypto_keys_get_ctx req = {};
|
||||||
|
struct spdk_accel_crypto_key *key = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (params && spdk_json_decode_object(params, rpc_accel_crypto_key_destroy_decoders,
|
||||||
|
SPDK_COUNTOF(rpc_accel_crypto_key_destroy_decoders),
|
||||||
|
&req)) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
|
||||||
|
"spdk_json_decode_object failed");
|
||||||
|
free(req.key_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = spdk_accel_crypto_key_get(req.key_name);
|
||||||
|
if (!key) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||||
|
"No key object found");
|
||||||
|
free(req.key_name);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
rc = spdk_accel_crypto_key_destroy(key);
|
||||||
|
if (rc) {
|
||||||
|
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||||
|
"Failed to destroy key, rc %d\n", rc);
|
||||||
|
} else {
|
||||||
|
spdk_jsonrpc_send_bool_response(request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(req.key_name);
|
||||||
|
}
|
||||||
|
SPDK_RPC_REGISTER("accel_crypto_key_destroy", rpc_accel_crypto_key_destroy, SPDK_RPC_RUNTIME)
|
||||||
|
@ -127,7 +127,7 @@ DEPDIRS-bdev_split := $(BDEV_DEPS)
|
|||||||
|
|
||||||
DEPDIRS-bdev_aio := $(BDEV_DEPS_THREAD)
|
DEPDIRS-bdev_aio := $(BDEV_DEPS_THREAD)
|
||||||
DEPDIRS-bdev_compress := $(BDEV_DEPS_THREAD) reduce
|
DEPDIRS-bdev_compress := $(BDEV_DEPS_THREAD) reduce
|
||||||
DEPDIRS-bdev_crypto := $(BDEV_DEPS_THREAD)
|
DEPDIRS-bdev_crypto := $(BDEV_DEPS_THREAD) accel
|
||||||
DEPDIRS-bdev_delay := $(BDEV_DEPS_THREAD)
|
DEPDIRS-bdev_delay := $(BDEV_DEPS_THREAD)
|
||||||
DEPDIRS-bdev_iscsi := $(BDEV_DEPS_THREAD)
|
DEPDIRS-bdev_iscsi := $(BDEV_DEPS_THREAD)
|
||||||
DEPDIRS-bdev_malloc := $(BDEV_DEPS_THREAD) accel
|
DEPDIRS-bdev_malloc := $(BDEV_DEPS_THREAD) accel
|
||||||
|
@ -601,6 +601,7 @@ accel_dpdk_cryptodev_mbuf_add_single_block(struct spdk_iov_sgl *sgl, struct rte_
|
|||||||
spdk_iov_sgl_advance(sgl, buf_len);
|
spdk_iov_sgl_advance(sgl, buf_len);
|
||||||
|
|
||||||
/* Handle the case of page boundary. */
|
/* Handle the case of page boundary. */
|
||||||
|
assert(task->base.block_size >= buf_len);
|
||||||
remainder = task->base.block_size - buf_len;
|
remainder = task->base.block_size - buf_len;
|
||||||
while (remainder) {
|
while (remainder) {
|
||||||
buf_len = spdk_min(remainder, sgl->iov->iov_len - sgl->iov_offset);
|
buf_len = spdk_min(remainder, sgl->iov->iov_len - sgl->iov_offset);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,43 +12,19 @@
|
|||||||
#include "spdk/util.h"
|
#include "spdk/util.h"
|
||||||
#include "spdk/string.h"
|
#include "spdk/string.h"
|
||||||
#include "spdk/log.h"
|
#include "spdk/log.h"
|
||||||
|
#include "spdk/accel.h"
|
||||||
|
#include "spdk_internal/accel_module.h"
|
||||||
|
|
||||||
#include "spdk/bdev.h"
|
#include "spdk/bdev.h"
|
||||||
|
|
||||||
#define AESNI_MB "crypto_aesni_mb"
|
#define BDEV_CRYPTO_DEFAULT_CIPHER "AES_CBC" /* QAT and AESNI_MB */
|
||||||
#define QAT "crypto_qat"
|
|
||||||
#define QAT_ASYM "crypto_qat_asym"
|
|
||||||
#define MLX5 "mlx5_pci"
|
|
||||||
|
|
||||||
/* Supported ciphers */
|
/* Structure to hold crypto options */
|
||||||
#define AES_CBC "AES_CBC" /* QAT and AESNI_MB */
|
|
||||||
#define AES_XTS "AES_XTS" /* QAT and MLX5 */
|
|
||||||
|
|
||||||
/* Specific to AES_CBC. */
|
|
||||||
#define AES_CBC_KEY_LENGTH 16
|
|
||||||
|
|
||||||
#define AES_XTS_128_BLOCK_KEY_LENGTH 16 /* AES-XTS-128 block key size. */
|
|
||||||
#define AES_XTS_256_BLOCK_KEY_LENGTH 32 /* AES-XTS-256 block key size. */
|
|
||||||
#define AES_XTS_512_BLOCK_KEY_LENGTH 64 /* AES-XTS-512 block key size. */
|
|
||||||
|
|
||||||
#define AES_XTS_TWEAK_KEY_LENGTH 16 /* XTS part key size is always 128 bit. */
|
|
||||||
|
|
||||||
/* Structure to hold crypto options for crypto pmd setup. */
|
|
||||||
struct vbdev_crypto_opts {
|
struct vbdev_crypto_opts {
|
||||||
char *vbdev_name; /* name of the vbdev to create */
|
char *vbdev_name; /* name of the vbdev to create */
|
||||||
char *bdev_name; /* base bdev name */
|
char *bdev_name; /* base bdev name */
|
||||||
|
struct spdk_accel_crypto_key *key; /* crypto key */
|
||||||
char *drv_name; /* name of the crypto device driver */
|
bool key_owner; /* If wet to true then the key was created by RPC and needs to be destroyed */
|
||||||
char *cipher; /* AES_CBC or AES_XTS */
|
|
||||||
|
|
||||||
/* Note, for dev/test we allow use of key in the config file, for production
|
|
||||||
* use, you must use an RPC to specify the key for security reasons.
|
|
||||||
*/
|
|
||||||
uint8_t *key; /* key per bdev */
|
|
||||||
uint8_t key_size; /* key size */
|
|
||||||
uint8_t *key2; /* key #2 for AES_XTS, per bdev */
|
|
||||||
uint8_t key2_size; /* key #2 size */
|
|
||||||
uint8_t *xts_key; /* key + key 2 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno);
|
typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno);
|
||||||
|
@ -9,14 +9,15 @@
|
|||||||
|
|
||||||
#include "spdk/hexlify.h"
|
#include "spdk/hexlify.h"
|
||||||
|
|
||||||
|
/* Reasonable bdev name length + cipher's name len */
|
||||||
|
#define MAX_KEY_NAME_LEN 128
|
||||||
|
|
||||||
/* Structure to hold the parameters for this RPC method. */
|
/* Structure to hold the parameters for this RPC method. */
|
||||||
struct rpc_construct_crypto {
|
struct rpc_construct_crypto {
|
||||||
char *base_bdev_name;
|
char *base_bdev_name;
|
||||||
char *name;
|
char *name;
|
||||||
char *crypto_pmd;
|
char *crypto_pmd;
|
||||||
char *key;
|
struct spdk_accel_crypto_key_create_param param;
|
||||||
char *cipher;
|
|
||||||
char *key2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Free the allocated memory resource after the RPC handling. */
|
/* Free the allocated memory resource after the RPC handling. */
|
||||||
@ -26,192 +27,54 @@ free_rpc_construct_crypto(struct rpc_construct_crypto *r)
|
|||||||
free(r->base_bdev_name);
|
free(r->base_bdev_name);
|
||||||
free(r->name);
|
free(r->name);
|
||||||
free(r->crypto_pmd);
|
free(r->crypto_pmd);
|
||||||
free(r->key);
|
free(r->param.cipher);
|
||||||
free(r->cipher);
|
if (r->param.hex_key) {
|
||||||
free(r->key2);
|
memset(r->param.hex_key, 0, strnlen(r->param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
|
||||||
|
free(r->param.hex_key);
|
||||||
|
}
|
||||||
|
if (r->param.hex_key2) {
|
||||||
|
memset(r->param.hex_key2, 0, strnlen(r->param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
|
||||||
|
free(r->param.hex_key2);
|
||||||
|
}
|
||||||
|
free(r->param.key_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Structure to decode the input parameters for this RPC method. */
|
/* Structure to decode the input parameters for this RPC method. */
|
||||||
static const struct spdk_json_object_decoder rpc_construct_crypto_decoders[] = {
|
static const struct spdk_json_object_decoder rpc_construct_crypto_decoders[] = {
|
||||||
{"base_bdev_name", offsetof(struct rpc_construct_crypto, base_bdev_name), spdk_json_decode_string},
|
{"base_bdev_name", offsetof(struct rpc_construct_crypto, base_bdev_name), spdk_json_decode_string},
|
||||||
{"name", offsetof(struct rpc_construct_crypto, name), spdk_json_decode_string},
|
{"name", offsetof(struct rpc_construct_crypto, name), spdk_json_decode_string},
|
||||||
{"crypto_pmd", offsetof(struct rpc_construct_crypto, crypto_pmd), spdk_json_decode_string},
|
{"crypto_pmd", offsetof(struct rpc_construct_crypto, crypto_pmd), spdk_json_decode_string, true},
|
||||||
{"key", offsetof(struct rpc_construct_crypto, key), spdk_json_decode_string},
|
{"key", offsetof(struct rpc_construct_crypto, param.hex_key), spdk_json_decode_string, true},
|
||||||
{"cipher", offsetof(struct rpc_construct_crypto, cipher), spdk_json_decode_string, true},
|
{"cipher", offsetof(struct rpc_construct_crypto, param.cipher), spdk_json_decode_string, true},
|
||||||
{"key2", offsetof(struct rpc_construct_crypto, key2), spdk_json_decode_string, true},
|
{"key2", offsetof(struct rpc_construct_crypto, param.hex_key2), spdk_json_decode_string, true},
|
||||||
|
{"key_name", offsetof(struct rpc_construct_crypto, param.key_name), spdk_json_decode_string, true},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Create crypto opts from rpc @req. Validate req fields and populate the
|
|
||||||
* correspoending fields in @opts.
|
|
||||||
*
|
|
||||||
* \param rpc Pointer to the rpc req.
|
|
||||||
* \param request Pointer to json request.
|
|
||||||
* \return Allocated and populated crypto opts or NULL on failure.
|
|
||||||
*/
|
|
||||||
static struct vbdev_crypto_opts *
|
static struct vbdev_crypto_opts *
|
||||||
create_crypto_opts(struct rpc_construct_crypto *rpc,
|
create_crypto_opts(struct rpc_construct_crypto *rpc, struct spdk_accel_crypto_key *key,
|
||||||
struct spdk_jsonrpc_request *request)
|
bool key_owner)
|
||||||
{
|
{
|
||||||
struct vbdev_crypto_opts *opts;
|
struct vbdev_crypto_opts *opts = calloc(1, sizeof(*opts));
|
||||||
int key_size, key2_size;
|
|
||||||
|
|
||||||
if (strcmp(rpc->crypto_pmd, AESNI_MB) == 0 && strcmp(rpc->cipher, AES_XTS) == 0) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid cipher. AES_XTS is not available on AESNI_MB.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(rpc->crypto_pmd, MLX5) == 0 && strcmp(rpc->cipher, AES_XTS) != 0) {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid cipher. %s is not available on MLX5.",
|
|
||||||
rpc->cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(rpc->cipher, AES_XTS) == 0 && rpc->key2 == NULL) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid key. A 2nd key is needed for AES_XTS.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(rpc->cipher, AES_CBC) == 0 && rpc->key2 != NULL) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid key. A 2nd key is needed only for AES_XTS.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = calloc(1, sizeof(struct vbdev_crypto_opts));
|
|
||||||
if (!opts) {
|
if (!opts) {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
||||||
"Failed to allocate memory for crypto_opts.");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
opts->bdev_name = strdup(rpc->base_bdev_name);
|
opts->bdev_name = strdup(rpc->base_bdev_name);
|
||||||
if (!opts->bdev_name) {
|
if (!opts->bdev_name) {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
free_crypto_opts(opts);
|
||||||
"Failed to allocate memory for bdev_name.");
|
return NULL;
|
||||||
goto error_alloc_bname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opts->vbdev_name = strdup(rpc->name);
|
opts->vbdev_name = strdup(rpc->name);
|
||||||
if (!opts->vbdev_name) {
|
if (!opts->vbdev_name) {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
free_crypto_opts(opts);
|
||||||
"Failed to allocate memory for vbdev_name.");
|
|
||||||
goto error_alloc_vname;
|
|
||||||
}
|
|
||||||
|
|
||||||
opts->drv_name = strdup(rpc->crypto_pmd);
|
|
||||||
if (!opts->drv_name) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
||||||
"Failed to allocate memory for drv_name.");
|
|
||||||
goto error_alloc_dname;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(opts->drv_name, MLX5) == 0) {
|
|
||||||
/* Only AES-XTS supported. */
|
|
||||||
|
|
||||||
/* We cannot use strlen() after spdk_unhexlify() because of possible \0 chars
|
|
||||||
* used in the key. Hexlified version of key is twice as longer. */
|
|
||||||
key_size = strnlen(rpc->key, (AES_XTS_512_BLOCK_KEY_LENGTH * 2) + 1);
|
|
||||||
if (key_size != AES_XTS_256_BLOCK_KEY_LENGTH * 2 &&
|
|
||||||
key_size != AES_XTS_512_BLOCK_KEY_LENGTH * 2) {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid AES_XTS key string length for mlx5: %d. "
|
|
||||||
"Supported sizes in hex form: %d or %d.",
|
|
||||||
key_size, AES_XTS_256_BLOCK_KEY_LENGTH * 2,
|
|
||||||
AES_XTS_512_BLOCK_KEY_LENGTH * 2);
|
|
||||||
goto error_invalid_key;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (strncmp(rpc->cipher, AES_XTS, sizeof(AES_XTS)) == 0) {
|
|
||||||
/* AES_XTS for qat uses 128bit key. */
|
|
||||||
key_size = strnlen(rpc->key, (AES_XTS_128_BLOCK_KEY_LENGTH * 2) + 1);
|
|
||||||
if (key_size != AES_XTS_128_BLOCK_KEY_LENGTH * 2) {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid AES_XTS key string length: %d. "
|
|
||||||
"Supported size in hex form: %d.",
|
|
||||||
key_size, AES_XTS_128_BLOCK_KEY_LENGTH * 2);
|
|
||||||
goto error_invalid_key;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
key_size = strnlen(rpc->key, (AES_CBC_KEY_LENGTH * 2) + 1);
|
|
||||||
if (key_size != AES_CBC_KEY_LENGTH * 2) {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid AES_CBC key string length: %d. "
|
|
||||||
"Supported size in hex form: %d.",
|
|
||||||
key_size, AES_CBC_KEY_LENGTH * 2);
|
|
||||||
goto error_invalid_key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opts->key = spdk_unhexlify(rpc->key);
|
|
||||||
if (!opts->key) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Failed to unhexlify key.");
|
|
||||||
goto error_alloc_key;
|
|
||||||
}
|
|
||||||
opts->key_size = key_size / 2;
|
|
||||||
|
|
||||||
if (strncmp(rpc->cipher, AES_XTS, sizeof(AES_XTS)) == 0) {
|
|
||||||
opts->cipher = AES_XTS;
|
|
||||||
assert(rpc->key2);
|
|
||||||
key2_size = strnlen(rpc->key2, (AES_XTS_TWEAK_KEY_LENGTH * 2) + 1);
|
|
||||||
if (key2_size != AES_XTS_TWEAK_KEY_LENGTH * 2) {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid AES_XTS key2 length %d. "
|
|
||||||
"Supported size in hex form: %d.",
|
|
||||||
key2_size, AES_XTS_TWEAK_KEY_LENGTH * 2);
|
|
||||||
goto error_invalid_key2;
|
|
||||||
}
|
|
||||||
opts->key2 = spdk_unhexlify(rpc->key2);
|
|
||||||
if (!opts->key2) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Failed to unhexlify key2.");
|
|
||||||
goto error_alloc_key2;
|
|
||||||
}
|
|
||||||
opts->key2_size = key2_size / 2;
|
|
||||||
|
|
||||||
/* DPDK expects the keys to be concatenated together. */
|
|
||||||
opts->xts_key = calloc(1, opts->key_size + opts->key2_size + 1);
|
|
||||||
if (opts->xts_key == NULL) {
|
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
||||||
"Failed to allocate memory for XTS key.");
|
|
||||||
goto error_alloc_xts;
|
|
||||||
}
|
|
||||||
memcpy(opts->xts_key, opts->key, opts->key_size);
|
|
||||||
memcpy(opts->xts_key + opts->key_size, opts->key2, opts->key2_size);
|
|
||||||
} else if (strncmp(rpc->cipher, AES_CBC, sizeof(AES_CBC)) == 0) {
|
|
||||||
opts->cipher = AES_CBC;
|
|
||||||
} else {
|
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
||||||
"Invalid param. Cipher %s is not supported.",
|
|
||||||
rpc->cipher);
|
|
||||||
goto error_cipher;
|
|
||||||
}
|
|
||||||
return opts;
|
|
||||||
|
|
||||||
/* Error cleanup paths. */
|
|
||||||
error_cipher:
|
|
||||||
error_alloc_xts:
|
|
||||||
error_alloc_key2:
|
|
||||||
error_invalid_key2:
|
|
||||||
if (opts->key) {
|
|
||||||
memset(opts->key, 0, opts->key_size);
|
|
||||||
free(opts->key);
|
|
||||||
}
|
|
||||||
opts->key_size = 0;
|
|
||||||
error_alloc_key:
|
|
||||||
error_invalid_key:
|
|
||||||
free(opts->drv_name);
|
|
||||||
error_alloc_dname:
|
|
||||||
free(opts->vbdev_name);
|
|
||||||
error_alloc_vname:
|
|
||||||
free(opts->bdev_name);
|
|
||||||
error_alloc_bname:
|
|
||||||
free(opts);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
opts->key = key;
|
||||||
|
opts->key_owner = key_owner;
|
||||||
|
|
||||||
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode the parameters for this RPC method and properly construct the crypto
|
/* Decode the parameters for this RPC method and properly construct the crypto
|
||||||
@ -221,30 +84,92 @@ static void
|
|||||||
rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
|
rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
|
||||||
const struct spdk_json_val *params)
|
const struct spdk_json_val *params)
|
||||||
{
|
{
|
||||||
struct rpc_construct_crypto req = {NULL};
|
struct rpc_construct_crypto req = {};
|
||||||
struct vbdev_crypto_opts *crypto_opts;
|
struct vbdev_crypto_opts *crypto_opts = NULL;
|
||||||
struct spdk_json_write_ctx *w;
|
struct spdk_json_write_ctx *w;
|
||||||
int rc;
|
struct spdk_accel_crypto_key *key = NULL;
|
||||||
|
struct spdk_accel_crypto_key *created_key = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
if (spdk_json_decode_object(params, rpc_construct_crypto_decoders,
|
if (spdk_json_decode_object(params, rpc_construct_crypto_decoders,
|
||||||
SPDK_COUNTOF(rpc_construct_crypto_decoders),
|
SPDK_COUNTOF(rpc_construct_crypto_decoders),
|
||||||
&req)) {
|
&req)) {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
|
||||||
"Failed to decode crypto disk create parameters.");
|
"Failed to decode crypto disk create parameters.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.cipher == NULL) {
|
if (!req.name) {
|
||||||
req.cipher = strdup(AES_CBC);
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||||
if (req.cipher == NULL) {
|
"crypto_bdev name is missing");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.param.key_name) {
|
||||||
|
/* New config version */
|
||||||
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
||||||
|
if (key) {
|
||||||
|
if (req.param.hex_key || req.param.cipher || req.crypto_pmd) {
|
||||||
|
SPDK_NOTICELOG("Key name specified, other parameters are ignored\n");
|
||||||
|
}
|
||||||
|
SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No key_name. Support legacy configuration */
|
||||||
|
if (!key) {
|
||||||
|
if (req.param.key_name) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
||||||
|
"Key was not found");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.param.cipher == NULL) {
|
||||||
|
req.param.cipher = strdup(BDEV_CRYPTO_DEFAULT_CIPHER);
|
||||||
|
if (req.param.cipher == NULL) {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
"Unable to allocate memory for req.cipher");
|
"Unable to allocate memory for req.cipher");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (req.crypto_pmd) {
|
||||||
|
SPDK_WARNLOG("\"crypto_pmd\" parameters is obsolete and ignored\n");
|
||||||
|
}
|
||||||
|
|
||||||
crypto_opts = create_crypto_opts(&req, request);
|
req.param.key_name = calloc(1, MAX_KEY_NAME_LEN);
|
||||||
if (crypto_opts == NULL) {
|
if (!req.param.key_name) {
|
||||||
|
/* The new API requires key name. Create it as pmd_name + cipher */
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
|
"Unable to allocate memory for key_name");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
snprintf(req.param.key_name, MAX_KEY_NAME_LEN, "%s_%s", req.name, req.param.cipher);
|
||||||
|
|
||||||
|
/* Try to find a key with generated name, we may be loading from a json config where crypto_bdev had no key_name parameter */
|
||||||
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
||||||
|
if (key) {
|
||||||
|
SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
|
||||||
|
} else {
|
||||||
|
rc = spdk_accel_crypto_key_create(&req.param);
|
||||||
|
if (!rc) {
|
||||||
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
||||||
|
created_key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
/* We haven't found an existing key or were not able to create a new one */
|
||||||
|
SPDK_ERRLOG("No key was found\n");
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
|
"No key was found");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_opts = create_crypto_opts(&req, key, created_key != NULL);
|
||||||
|
if (!crypto_opts) {
|
||||||
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
|
"Memory allocation failed");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +183,11 @@ rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
|
|||||||
w = spdk_jsonrpc_begin_result(request);
|
w = spdk_jsonrpc_begin_result(request);
|
||||||
spdk_json_write_string(w, req.name);
|
spdk_json_write_string(w, req.name);
|
||||||
spdk_jsonrpc_end_result(request, w);
|
spdk_jsonrpc_end_result(request, w);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (rc && created_key) {
|
||||||
|
spdk_accel_crypto_key_destroy(created_key);
|
||||||
|
}
|
||||||
free_rpc_construct_crypto(&req);
|
free_rpc_construct_crypto(&req);
|
||||||
}
|
}
|
||||||
SPDK_RPC_REGISTER("bdev_crypto_create", rpc_bdev_crypto_create, SPDK_RPC_RUNTIME)
|
SPDK_RPC_REGISTER("bdev_crypto_create", rpc_bdev_crypto_create, SPDK_RPC_RUNTIME)
|
||||||
|
@ -54,6 +54,19 @@ def accel_crypto_key_create(client, cipher, key, key2, name):
|
|||||||
return client.call('accel_crypto_key_create', params)
|
return client.call('accel_crypto_key_create', params)
|
||||||
|
|
||||||
|
|
||||||
|
def accel_crypto_key_destroy(client, name):
|
||||||
|
"""Destroy Data Encryption Key.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: key name
|
||||||
|
"""
|
||||||
|
params = {
|
||||||
|
'name': name
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.call('accel_crypto_key_destroy', params)
|
||||||
|
|
||||||
|
|
||||||
def accel_crypto_keys_get(client, key_name):
|
def accel_crypto_keys_get(client, key_name):
|
||||||
"""Get a list of the crypto keys.
|
"""Get a list of the crypto keys.
|
||||||
|
|
||||||
|
@ -104,23 +104,33 @@ def bdev_compress_get_orphans(client, name=None):
|
|||||||
return client.call('bdev_compress_get_orphans', params)
|
return client.call('bdev_compress_get_orphans', params)
|
||||||
|
|
||||||
|
|
||||||
def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd, key, cipher=None, key2=None):
|
def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd=None, key=None, cipher=None, key2=None, key_name=None):
|
||||||
"""Construct a crypto virtual block device.
|
"""Construct a crypto virtual block device.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
base_bdev_name: name of the underlying base bdev
|
base_bdev_name: name of the underlying base bdev
|
||||||
name: name for the crypto vbdev
|
name: name for the crypto vbdev
|
||||||
crypto_pmd: name of of the DPDK crypto driver to use
|
crypto_pmd: name of the DPDK crypto driver to use
|
||||||
key: key
|
key: key
|
||||||
|
cipher: crypto algorithm to use
|
||||||
|
key2: Optional second part of the key
|
||||||
|
key_name: The key name to use in crypto operations
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Name of created virtual block device.
|
Name of created virtual block device.
|
||||||
"""
|
"""
|
||||||
params = {'base_bdev_name': base_bdev_name, 'name': name, 'crypto_pmd': crypto_pmd, 'key': key}
|
params = {'base_bdev_name': base_bdev_name, 'name': name}
|
||||||
if cipher:
|
|
||||||
params['cipher'] = cipher
|
if crypto_pmd is not None:
|
||||||
if key2:
|
params['crypto_pmd'] = crypto_pmd
|
||||||
|
if key is not None:
|
||||||
|
params['key'] = key
|
||||||
|
if key2 is not None:
|
||||||
params['key2'] = key2
|
params['key2'] = key2
|
||||||
|
if cipher is not None:
|
||||||
|
params['cipher'] = cipher
|
||||||
|
if key_name is not None:
|
||||||
|
params['key_name'] = key_name
|
||||||
return client.call('bdev_crypto_create', params)
|
return client.call('bdev_crypto_create', params)
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,10 +23,8 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
|||||||
|
|
||||||
def init(self, client, params):
|
def init(self, client, params):
|
||||||
super().init(client, params)
|
super().init(client, params)
|
||||||
driver = params.get('driver')
|
# _driver can be None
|
||||||
if driver is None:
|
self._driver = params.get('driver')
|
||||||
raise ValueError('Crypto driver must be configured for bdev_crypto')
|
|
||||||
self._driver = driver
|
|
||||||
|
|
||||||
def setup(self, volume_id, key, cipher, key2=None):
|
def setup(self, volume_id, key, cipher, key2=None):
|
||||||
try:
|
try:
|
||||||
@ -37,9 +35,10 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
|||||||
'Invalid volume crypto configuration: bad cipher')
|
'Invalid volume crypto configuration: bad cipher')
|
||||||
params = {'base_bdev_name': volume_id,
|
params = {'base_bdev_name': volume_id,
|
||||||
'name': str(uuid.uuid4()),
|
'name': str(uuid.uuid4()),
|
||||||
'crypto_pmd': self._driver,
|
|
||||||
'key': key,
|
'key': key,
|
||||||
'cipher': cipher}
|
'cipher': cipher}
|
||||||
|
if self._driver is not None:
|
||||||
|
params['crypto_pmd'] = self._driver
|
||||||
if key2 is not None:
|
if key2 is not None:
|
||||||
params['key2'] = key2
|
params['key2'] = key2
|
||||||
log.info('Creating crypto bdev: {} on volume: {}'.format(
|
log.info('Creating crypto bdev: {} on volume: {}'.format(
|
||||||
@ -72,19 +71,26 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
|||||||
if key is None:
|
if key is None:
|
||||||
return
|
return
|
||||||
params = crypto_bdev['driver_specific']['crypto']
|
params = crypto_bdev['driver_specific']['crypto']
|
||||||
|
crypto_key = self._get_crypto_key(params['key_name'])
|
||||||
|
if crypto_key is None:
|
||||||
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
|
'No key object found')
|
||||||
cipher = self._ciphers.get(cipher)
|
cipher = self._ciphers.get(cipher)
|
||||||
if cipher is None:
|
if cipher is None:
|
||||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
'Invalid volume crypto configuration: bad cipher')
|
'Invalid volume crypto configuration: bad cipher')
|
||||||
if params['cipher'].lower() != cipher.lower():
|
if crypto_key['cipher'].lower() != cipher.lower():
|
||||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
'Invalid volume crypto configuration: bad cipher')
|
'Invalid volume crypto configuration: bad cipher')
|
||||||
if params['key'].lower() != key.lower():
|
if crypto_key['key'].lower() != key.lower():
|
||||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
'Invalid volume crypto configuration: bad key')
|
'Invalid volume crypto configuration: bad key')
|
||||||
if key2 is not None and params.get('key2', '').lower() != key2.lower():
|
if key2 is not None and crypto_key.get('key2', '').lower() != key2.lower():
|
||||||
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
'Invalid volume crypto configuration: bad key2')
|
'Invalid volume crypto configuration: bad key2')
|
||||||
|
if crypto_key['name'].lower() != params['key_name'].lower():
|
||||||
|
raise crypto.CryptoException(grpc.StatusCode.INVALID_ARGUMENT,
|
||||||
|
'Invalid volume crypto configuration: key name does not match')
|
||||||
|
|
||||||
def _get_crypto_bdev(self, volume_id):
|
def _get_crypto_bdev(self, volume_id):
|
||||||
try:
|
try:
|
||||||
@ -106,6 +112,16 @@ class CryptoEngineBdev(crypto.CryptoEngine):
|
|||||||
raise crypto.CryptoException(grpc.StatusCode.INTERNAL,
|
raise crypto.CryptoException(grpc.StatusCode.INTERNAL,
|
||||||
f'Failed to get bdev_crypto for volume: {volume_id}')
|
f'Failed to get bdev_crypto for volume: {volume_id}')
|
||||||
|
|
||||||
|
def _get_crypto_key(self, key_name):
|
||||||
|
try:
|
||||||
|
with self._client() as client:
|
||||||
|
_keys = client.call('accel_crypto_keys_get', {'key_name': key_name})
|
||||||
|
if _keys is not None:
|
||||||
|
return _keys[0]
|
||||||
|
return None
|
||||||
|
except JSONRPCException:
|
||||||
|
pass
|
||||||
|
|
||||||
def get_crypto_bdev(self, volume_id):
|
def get_crypto_bdev(self, volume_id):
|
||||||
bdev = self._get_crypto_bdev(volume_id)
|
bdev = self._get_crypto_bdev(volume_id)
|
||||||
if bdev is not None:
|
if bdev is not None:
|
||||||
|
@ -277,14 +277,16 @@ if __name__ == "__main__":
|
|||||||
crypto_pmd=args.crypto_pmd,
|
crypto_pmd=args.crypto_pmd,
|
||||||
key=args.key,
|
key=args.key,
|
||||||
cipher=args.cipher,
|
cipher=args.cipher,
|
||||||
key2=args.key2))
|
key2=args.key2,
|
||||||
|
key_name=args.key_name))
|
||||||
p = subparsers.add_parser('bdev_crypto_create', help='Add a crypto vbdev')
|
p = subparsers.add_parser('bdev_crypto_create', help='Add a crypto vbdev')
|
||||||
p.add_argument('base_bdev_name', help="Name of the base bdev")
|
p.add_argument('base_bdev_name', help="Name of the base bdev")
|
||||||
p.add_argument('name', help="Name of the crypto vbdev")
|
p.add_argument('name', help="Name of the crypto vbdev")
|
||||||
p.add_argument('crypto_pmd', help="Name of the crypto device driver")
|
p.add_argument('-p', '--crypto-pmd', help="Name of the crypto device driver. Obsolete, see dpdk_cryptodev_set_driver", required=False)
|
||||||
p.add_argument('key', help="Key")
|
p.add_argument('-k', '--key', help="Key. Obsolete, see accel_crypto_key_create", required=False)
|
||||||
p.add_argument('-c', '--cipher', help="cipher to use, AES_CBC or AES_XTS (QAT only)")
|
p.add_argument('-c', '--cipher', help="cipher to use. Obsolete, see accel_crypto_key_create", required=False)
|
||||||
p.add_argument('-k2', '--key2', help="2nd key for cipher AES_XTS", default=None)
|
p.add_argument('-k2', '--key2', help="2nd key for cipher AES_XTS. Obsolete, see accel_crypto_key_create", default=None)
|
||||||
|
p.add_argument('-n', '--key-name', help="Key name to use, see accel_crypto_key_create", required=False)
|
||||||
p.set_defaults(func=bdev_crypto_create)
|
p.set_defaults(func=bdev_crypto_create)
|
||||||
|
|
||||||
def bdev_crypto_delete(args):
|
def bdev_crypto_delete(args):
|
||||||
@ -2835,6 +2837,14 @@ Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 mse
|
|||||||
p.add_argument('-n', '--name', help='key name', required=True, type=str)
|
p.add_argument('-n', '--name', help='key name', required=True, type=str)
|
||||||
p.set_defaults(func=accel_crypto_key_create)
|
p.set_defaults(func=accel_crypto_key_create)
|
||||||
|
|
||||||
|
def accel_crypto_key_destroy(args):
|
||||||
|
print_dict(rpc.accel.accel_crypto_key_destroy(args.client,
|
||||||
|
name=args.name))
|
||||||
|
|
||||||
|
p = subparsers.add_parser('accel_crypto_key_destroy', help='Destroy encryption key')
|
||||||
|
p.add_argument('-n', '--name', help='key name', required=True, type=str)
|
||||||
|
p.set_defaults(func=accel_crypto_key_destroy)
|
||||||
|
|
||||||
def accel_crypto_keys_get(args):
|
def accel_crypto_keys_get(args):
|
||||||
print_dict(rpc.accel.accel_crypto_keys_get(args.client,
|
print_dict(rpc.accel.accel_crypto_keys_get(args.client,
|
||||||
key_name=args.key_name))
|
key_name=args.key_name))
|
||||||
|
@ -48,7 +48,7 @@ function cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function start_spdk_tgt() {
|
function start_spdk_tgt() {
|
||||||
"$SPDK_BIN_DIR/spdk_tgt" "$env_ctx" &
|
"$SPDK_BIN_DIR/spdk_tgt" "$env_ctx" "$wait_for_rpc" &
|
||||||
spdk_tgt_pid=$!
|
spdk_tgt_pid=$!
|
||||||
trap 'killprocess "$spdk_tgt_pid"; exit 1' SIGINT SIGTERM EXIT
|
trap 'killprocess "$spdk_tgt_pid"; exit 1' SIGINT SIGTERM EXIT
|
||||||
waitforlisten "$spdk_tgt_pid"
|
waitforlisten "$spdk_tgt_pid"
|
||||||
@ -137,10 +137,23 @@ function setup_gpt_conf() {
|
|||||||
function setup_crypto_aesni_conf() {
|
function setup_crypto_aesni_conf() {
|
||||||
# Malloc0 and Malloc1 use AESNI
|
# Malloc0 and Malloc1 use AESNI
|
||||||
"$rpc_py" <<- RPC
|
"$rpc_py" <<- RPC
|
||||||
bdev_malloc_create -b Malloc0 16 512
|
dpdk_cryptodev_scan_accel_module
|
||||||
bdev_malloc_create -b Malloc1 16 512
|
dpdk_cryptodev_set_driver -d crypto_aesni_mb
|
||||||
bdev_crypto_create Malloc0 crypto_ram crypto_aesni_mb 01234567891234560123456789123456
|
accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
bdev_crypto_create Malloc1 crypto_ram2 crypto_aesni_mb 90123456789123459012345678912345
|
accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
framework_start_init
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 01234567891234560123456789123456 -n test_dek_aesni_cbc_1
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 12345678912345601234567891234560 -n test_dek_aesni_cbc_2
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 23456789123456012345678912345601 -n test_dek_aesni_cbc_3
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 34567891234560123456789123456012 -n test_dek_aesni_cbc_4
|
||||||
|
bdev_malloc_create -b Malloc0 32 512
|
||||||
|
bdev_malloc_create -b Malloc1 32 512
|
||||||
|
bdev_malloc_create -b Malloc2 32 4096
|
||||||
|
bdev_malloc_create -b Malloc3 32 4096
|
||||||
|
bdev_crypto_create Malloc0 crypto_ram -n test_dek_aesni_cbc_1
|
||||||
|
bdev_crypto_create Malloc1 crypto_ram2 -n test_dek_aesni_cbc_2
|
||||||
|
bdev_crypto_create Malloc2 crypto_ram3 -n test_dek_aesni_cbc_3
|
||||||
|
bdev_crypto_create Malloc3 crypto_ram4 -n test_dek_aesni_cbc_4
|
||||||
RPC
|
RPC
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +161,36 @@ function setup_crypto_qat_conf() {
|
|||||||
# Malloc0 will use QAT AES_CBC
|
# Malloc0 will use QAT AES_CBC
|
||||||
# Malloc1 will use QAT AES_XTS
|
# Malloc1 will use QAT AES_XTS
|
||||||
"$rpc_py" <<- RPC
|
"$rpc_py" <<- RPC
|
||||||
|
dpdk_cryptodev_scan_accel_module
|
||||||
|
dpdk_cryptodev_set_driver -d crypto_qat
|
||||||
|
accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
framework_start_init
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 01234567891234560123456789123456 -n test_dek_qat_cbc
|
||||||
|
accel_crypto_key_create -c AES_XTS -k 00112233445566778899001122334455 -e 12345678912345601234567891234560 -n test_dek_qat_xts
|
||||||
|
accel_crypto_key_create -c AES_CBC -k 23456789123456012345678912345601 -n test_dek_qat_cbc2
|
||||||
|
accel_crypto_key_create -c AES_XTS -k 22334455667788990011223344550011 -e 34567891234560123456789123456012 -n test_dek_qat_xts2
|
||||||
|
bdev_malloc_create -b Malloc0 32 512
|
||||||
|
bdev_malloc_create -b Malloc1 32 512
|
||||||
|
bdev_malloc_create -b Malloc2 32 4096
|
||||||
|
bdev_malloc_create -b Malloc3 32 4096
|
||||||
|
bdev_crypto_create Malloc0 crypto_ram -n test_dek_qat_cbc
|
||||||
|
bdev_crypto_create Malloc1 crypto_ram1 -n test_dek_qat_xts
|
||||||
|
bdev_crypto_create Malloc2 crypto_ram2 -n test_dek_qat_cbc2
|
||||||
|
bdev_crypto_create Malloc3 crypto_ram3 -n test_dek_qat_xts2
|
||||||
|
bdev_get_bdevs -b Malloc1
|
||||||
|
RPC
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_crypto_sw_conf() {
|
||||||
|
"$rpc_py" <<- RPC
|
||||||
|
framework_start_init
|
||||||
bdev_malloc_create -b Malloc0 16 512
|
bdev_malloc_create -b Malloc0 16 512
|
||||||
bdev_malloc_create -b Malloc1 16 512
|
bdev_malloc_create -b Malloc1 16 4096
|
||||||
bdev_crypto_create Malloc0 crypto_ram crypto_qat 01234567891234560123456789123456
|
accel_crypto_key_create -c AES_XTS -k 00112233445566778899001122334455 -e 11223344556677889900112233445500 -n test_dek_sw
|
||||||
bdev_crypto_create -c AES_XTS -k2 01234567891234560123456789123456 Malloc1 crypto_ram3 crypto_qat 01234567891234560123456789123456
|
accel_crypto_key_create -c AES_XTS -k 22334455667788990011223344550011 -e 33445566778899001122334455001122 -n test_dek_sw2
|
||||||
|
bdev_crypto_create Malloc0 crypto_ram -n test_dek_sw
|
||||||
|
bdev_crypto_create Malloc1 crypto_ram2 -n test_dek_sw2
|
||||||
bdev_get_bdevs -b Malloc1
|
bdev_get_bdevs -b Malloc1
|
||||||
RPC
|
RPC
|
||||||
}
|
}
|
||||||
@ -182,8 +221,13 @@ function setup_crypto_mlx5_conf() {
|
|||||||
|
|
||||||
# Malloc0 will use MLX5 AES_XTS
|
# Malloc0 will use MLX5 AES_XTS
|
||||||
"$rpc_py" <<- RPC
|
"$rpc_py" <<- RPC
|
||||||
|
dpdk_cryptodev_scan_accel_module
|
||||||
|
dpdk_cryptodev_set_driver -d mlx5_pci
|
||||||
|
accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
framework_start_init
|
||||||
bdev_malloc_create -b Malloc0 16 512
|
bdev_malloc_create -b Malloc0 16 512
|
||||||
bdev_crypto_create -c AES_XTS -k2 $tweak_key Malloc0 crypto_ram4 mlx5_pci $block_key
|
bdev_crypto_create Malloc0 crypto_ram4 -k $block_key -c AES_XTS -k2 $tweak_key
|
||||||
bdev_get_bdevs -b Malloc0
|
bdev_get_bdevs -b Malloc0
|
||||||
RPC
|
RPC
|
||||||
}
|
}
|
||||||
@ -570,6 +614,7 @@ crypto_device=$2
|
|||||||
wcs_file=$3
|
wcs_file=$3
|
||||||
dek=$4
|
dek=$4
|
||||||
env_ctx=""
|
env_ctx=""
|
||||||
|
wait_for_rpc=""
|
||||||
if [ -n "$crypto_device" ] && [ -n "$wcs_file" ]; then
|
if [ -n "$crypto_device" ] && [ -n "$wcs_file" ]; then
|
||||||
# We need full path here since fio perf test does 'pushd' to the test dir
|
# We need full path here since fio perf test does 'pushd' to the test dir
|
||||||
# and crypto login of fio plugin test can fail.
|
# and crypto login of fio plugin test can fail.
|
||||||
@ -581,6 +626,9 @@ if [ -n "$crypto_device" ] && [ -n "$wcs_file" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if [[ $test_type == crypto_* ]]; then
|
||||||
|
wait_for_rpc="--wait-for-rpc"
|
||||||
|
fi
|
||||||
start_spdk_tgt
|
start_spdk_tgt
|
||||||
case "$test_type" in
|
case "$test_type" in
|
||||||
bdev)
|
bdev)
|
||||||
@ -598,6 +646,9 @@ case "$test_type" in
|
|||||||
crypto_qat)
|
crypto_qat)
|
||||||
setup_crypto_qat_conf
|
setup_crypto_qat_conf
|
||||||
;;
|
;;
|
||||||
|
crypto_sw)
|
||||||
|
setup_crypto_sw_conf
|
||||||
|
;;
|
||||||
crypto_mlx5)
|
crypto_mlx5)
|
||||||
setup_crypto_mlx5_conf $dek
|
setup_crypto_mlx5_conf $dek
|
||||||
;;
|
;;
|
||||||
@ -627,6 +678,7 @@ esac
|
|||||||
# Generate json config and use it throughout all the tests
|
# Generate json config and use it throughout all the tests
|
||||||
cat <<- CONF > "$conf_file"
|
cat <<- CONF > "$conf_file"
|
||||||
{"subsystems":[
|
{"subsystems":[
|
||||||
|
$("$rpc_py" save_subsystem_config -n accel),
|
||||||
$("$rpc_py" save_subsystem_config -n bdev)
|
$("$rpc_py" save_subsystem_config -n bdev)
|
||||||
]}
|
]}
|
||||||
CONF
|
CONF
|
||||||
|
@ -41,6 +41,10 @@ def filter_methods(do_remove_global_rpcs):
|
|||||||
'sock_impl_set_options',
|
'sock_impl_set_options',
|
||||||
'sock_set_default_impl',
|
'sock_set_default_impl',
|
||||||
'framework_set_scheduler',
|
'framework_set_scheduler',
|
||||||
|
'accel_crypto_key_create',
|
||||||
|
'accel_assign_opc',
|
||||||
|
'dpdk_cryptodev_scan_accel_module',
|
||||||
|
'dpdk_cryptodev_set_driver',
|
||||||
]
|
]
|
||||||
|
|
||||||
data = json.loads(sys.stdin.read())
|
data = json.loads(sys.stdin.read())
|
||||||
|
@ -143,6 +143,18 @@ function json_config_test_shutdown_app() {
|
|||||||
echo "SPDK $app shutdown done"
|
echo "SPDK $app shutdown done"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function create_accel_config() {
|
||||||
|
timing_enter "${FUNCNAME[0]}"
|
||||||
|
|
||||||
|
if [[ $SPDK_TEST_CRYPTO -eq 1 ]]; then
|
||||||
|
tgt_rpc dpdk_cryptodev_scan_accel_module
|
||||||
|
tgt_rpc accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
tgt_rpc accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
fi
|
||||||
|
|
||||||
|
timing_exit "${FUNCNAME[0]}"
|
||||||
|
}
|
||||||
|
|
||||||
function create_bdev_subsystem_config() {
|
function create_bdev_subsystem_config() {
|
||||||
timing_enter "${FUNCNAME[0]}"
|
timing_enter "${FUNCNAME[0]}"
|
||||||
|
|
||||||
@ -206,7 +218,7 @@ function create_bdev_subsystem_config() {
|
|||||||
local crypto_driver=crypto_qat
|
local crypto_driver=crypto_qat
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tgt_rpc bdev_crypto_create MallocForCryptoBdev CryptoMallocBdev $crypto_driver 01234567891234560123456789123456
|
tgt_rpc bdev_crypto_create MallocForCryptoBdev CryptoMallocBdev -p $crypto_driver -k 01234567891234560123456789123456
|
||||||
expected_notifications+=(
|
expected_notifications+=(
|
||||||
bdev_register:MallocForCryptoBdev
|
bdev_register:MallocForCryptoBdev
|
||||||
bdev_register:CryptoMallocBdev
|
bdev_register:CryptoMallocBdev
|
||||||
@ -324,6 +336,8 @@ function json_config_test_init() {
|
|||||||
|
|
||||||
#TODO: global subsystem params
|
#TODO: global subsystem params
|
||||||
|
|
||||||
|
create_accel_config
|
||||||
|
|
||||||
# Load nvme configuration. The load_config will issue framework_start_init automatically
|
# Load nvme configuration. The load_config will issue framework_start_init automatically
|
||||||
(
|
(
|
||||||
$rootdir/scripts/gen_nvme.sh --json-with-subsystems
|
$rootdir/scripts/gen_nvme.sh --json-with-subsystems
|
||||||
|
@ -144,9 +144,18 @@ verify_crypto_volume() {
|
|||||||
|
|
||||||
trap "cleanup; exit 1" SIGINT SIGTERM EXIT
|
trap "cleanup; exit 1" SIGINT SIGTERM EXIT
|
||||||
|
|
||||||
"$rootdir/build/bin/spdk_tgt" -m 0x1 &
|
"$rootdir/build/bin/spdk_tgt" -m 0x1 --wait-for-rpc &
|
||||||
hostpid=$!
|
hostpid=$!
|
||||||
|
|
||||||
|
waitforlisten $hostpid
|
||||||
|
|
||||||
|
# Configure host with accel crypto parameters
|
||||||
|
$rpc_py dpdk_cryptodev_scan_accel_module
|
||||||
|
rpc_cmd dpdk_cryptodev_set_driver -d crypto_aesni_mb
|
||||||
|
$rpc_py accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
$rpc_py accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
$rpc_py framework_start_init
|
||||||
|
|
||||||
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" -m 0x2 &
|
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" -m 0x2 &
|
||||||
tgtpid=$!
|
tgtpid=$!
|
||||||
|
|
||||||
@ -158,8 +167,6 @@ $rootdir/scripts/sma.py -c <(
|
|||||||
- name: 'nvmf_tcp'
|
- name: 'nvmf_tcp'
|
||||||
crypto:
|
crypto:
|
||||||
name: 'bdev_crypto'
|
name: 'bdev_crypto'
|
||||||
params:
|
|
||||||
driver: 'crypto_aesni_mb'
|
|
||||||
CONFIG
|
CONFIG
|
||||||
) &
|
) &
|
||||||
smapid=$!
|
smapid=$!
|
||||||
@ -202,7 +209,10 @@ attach_volume $device $uuid AES_CBC $key0
|
|||||||
verify_crypto_volume $localnqn $uuid
|
verify_crypto_volume $localnqn $uuid
|
||||||
# Check that it's using correct key
|
# Check that it's using correct key
|
||||||
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
|
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
|
||||||
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev") == "$key0" ]]
|
key_name=$(jq -r '.driver_specific.crypto.key_name' <<< "$crypto_bdev")
|
||||||
|
key_obj=$(rpc_cmd accel_crypto_keys_get -k $key_name)
|
||||||
|
[[ $(jq -r '.[0].key' <<< "$key_obj") == "$key0" ]]
|
||||||
|
[[ $(jq -r '.[0].cipher' <<< "$key_obj") == "AES_CBC" ]]
|
||||||
|
|
||||||
# Attach the same volume again
|
# Attach the same volume again
|
||||||
attach_volume $device $uuid AES_CBC $key0
|
attach_volume $device $uuid AES_CBC $key0
|
||||||
@ -213,7 +223,10 @@ attach_volume $device $uuid AES_CBC $key0
|
|||||||
verify_crypto_volume $localnqn $uuid
|
verify_crypto_volume $localnqn $uuid
|
||||||
crypto_bdev2=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
|
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 '.name' <<< "$crypto_bdev") == $(jq -r '.name' <<< "$crypto_bdev2") ]]
|
||||||
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev2") == "$key0" ]]
|
key_name=$(jq -r '.driver_specific.crypto.key_name' <<< "$crypto_bdev2")
|
||||||
|
key_obj=$(rpc_cmd accel_crypto_keys_get -k $key_name)
|
||||||
|
[[ $(jq -r '.[0].key' <<< "$key_obj") == "$key0" ]]
|
||||||
|
[[ $(jq -r '.[0].cipher' <<< "$key_obj") == "AES_CBC" ]]
|
||||||
|
|
||||||
# Try to do attach it again, but this time use a different crypto algorithm
|
# Try to do attach it again, but this time use a different crypto algorithm
|
||||||
NOT attach_volume $device $uuid AES_XTS $key0
|
NOT attach_volume $device $uuid AES_XTS $key0
|
||||||
|
@ -125,10 +125,17 @@ vm_run $vm_no
|
|||||||
vm_wait_for_boot 300 $vm_no
|
vm_wait_for_boot 300 $vm_no
|
||||||
|
|
||||||
# Start SPDK
|
# Start SPDK
|
||||||
$rootdir/build/bin/spdk_tgt &
|
$rootdir/build/bin/spdk_tgt --wait-for-rpc &
|
||||||
tgtpid=$!
|
tgtpid=$!
|
||||||
waitforlisten $tgtpid
|
waitforlisten $tgtpid
|
||||||
|
|
||||||
|
# Configure accel crypto module & operations
|
||||||
|
rpc_cmd dpdk_cryptodev_scan_accel_module
|
||||||
|
rpc_cmd dpdk_cryptodev_set_driver -d crypto_aesni_mb
|
||||||
|
rpc_cmd accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
rpc_cmd accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
rpc_cmd framework_start_init
|
||||||
|
|
||||||
# Prepare the target
|
# Prepare the target
|
||||||
rpc_cmd bdev_null_create null0 100 4096
|
rpc_cmd bdev_null_create null0 100 4096
|
||||||
rpc_cmd bdev_null_create null1 100 4096
|
rpc_cmd bdev_null_create null1 100 4096
|
||||||
@ -148,8 +155,6 @@ $rootdir/scripts/sma.py -c <(
|
|||||||
qmp_port: 10005
|
qmp_port: 10005
|
||||||
crypto:
|
crypto:
|
||||||
name: 'bdev_crypto'
|
name: 'bdev_crypto'
|
||||||
params:
|
|
||||||
driver: 'crypto_aesni_mb'
|
|
||||||
EOF
|
EOF
|
||||||
) &
|
) &
|
||||||
smapid=$!
|
smapid=$!
|
||||||
@ -304,7 +309,10 @@ ns_bdev=$(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:vfiouser-0 | jq -r '.[
|
|||||||
crypto_bdev=$(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[] | select(.product_name == "crypto")')
|
crypto_bdev=$(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[] | select(.product_name == "crypto")')
|
||||||
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 1 ]]
|
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 1 ]]
|
||||||
|
|
||||||
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev") == "$key0" ]]
|
key_name=$(jq -r '.driver_specific.crypto.key_name' <<< "$crypto_bdev")
|
||||||
|
key_obj=$(rpc_cmd accel_crypto_keys_get -k $key_name)
|
||||||
|
[[ $(jq -r '.[0].key' <<< "$key_obj") == "$key0" ]]
|
||||||
|
[[ $(jq -r '.[0].cipher' <<< "$key_obj") == "AES_CBC" ]]
|
||||||
|
|
||||||
detach_volume "$device0" "$uuid0"
|
detach_volume "$device0" "$uuid0"
|
||||||
delete_device "$device0"
|
delete_device "$device0"
|
||||||
|
@ -58,9 +58,18 @@ vm_run $vm_no
|
|||||||
vm_wait_for_boot 300 $vm_no
|
vm_wait_for_boot 300 $vm_no
|
||||||
timing_exit setup_vm
|
timing_exit setup_vm
|
||||||
|
|
||||||
$rootdir/build/bin/vhost -S /var/tmp -m 0x3 &
|
$rootdir/build/bin/vhost -S /var/tmp -m 0x3 --wait-for-rpc &
|
||||||
vhostpid=$!
|
vhostpid=$!
|
||||||
|
|
||||||
|
waitforlisten $vhostpid
|
||||||
|
|
||||||
|
# Configure accel crypto module & operations
|
||||||
|
rpc_cmd dpdk_cryptodev_scan_accel_module
|
||||||
|
rpc_cmd dpdk_cryptodev_set_driver -d crypto_aesni_mb
|
||||||
|
rpc_cmd accel_assign_opc -o encrypt -m dpdk_cryptodev
|
||||||
|
rpc_cmd accel_assign_opc -o decrypt -m dpdk_cryptodev
|
||||||
|
rpc_cmd framework_start_init
|
||||||
|
|
||||||
$rootdir/scripts/sma.py -c <(
|
$rootdir/scripts/sma.py -c <(
|
||||||
cat <<- EOF
|
cat <<- EOF
|
||||||
address: 127.0.0.1
|
address: 127.0.0.1
|
||||||
@ -77,8 +86,6 @@ $rootdir/scripts/sma.py -c <(
|
|||||||
qmp_port: 9090
|
qmp_port: 9090
|
||||||
crypto:
|
crypto:
|
||||||
name: 'bdev_crypto'
|
name: 'bdev_crypto'
|
||||||
params:
|
|
||||||
driver: 'crypto_aesni_mb'
|
|
||||||
EOF
|
EOF
|
||||||
) &
|
) &
|
||||||
smapid=$!
|
smapid=$!
|
||||||
@ -191,8 +198,11 @@ devid0=$(
|
|||||||
bdev=$(rpc_cmd vhost_get_controllers | jq -r '.[].backend_specific.block.bdev')
|
bdev=$(rpc_cmd vhost_get_controllers | jq -r '.[].backend_specific.block.bdev')
|
||||||
|
|
||||||
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
|
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
|
||||||
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev") == "$key0" ]]
|
|
||||||
[[ $(jq -r '.driver_specific.crypto.name' <<< "$crypto_bdev") == "$bdev" ]]
|
[[ $(jq -r '.driver_specific.crypto.name' <<< "$crypto_bdev") == "$bdev" ]]
|
||||||
|
key_name=$(jq -r '.driver_specific.crypto.key_name' <<< "$crypto_bdev")
|
||||||
|
key_obj=$(rpc_cmd accel_crypto_keys_get -k $key_name)
|
||||||
|
[[ $(jq -r '.[0].key' <<< "$key_obj") == "$key0" ]]
|
||||||
|
[[ $(jq -r '.[0].cipher' <<< "$key_obj") == "AES_CBC" ]]
|
||||||
|
|
||||||
# Delete crypto device and check if it's gone
|
# Delete crypto device and check if it's gone
|
||||||
delete_device $devid0
|
delete_device $devid0
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user