module/crypto: add RPC and plumbing to support QAT AES_XTS cipher

Signed-off-by: paul luse <paul.e.luse@intel.com>
Change-Id: Iadd03f8da305e97e3f1d57ef4aeaece400e8d959
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/441
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
paul luse 2020-01-31 22:19:09 +00:00 committed by Tomasz Zawadzki
parent 9e1b82ac9c
commit f070b78cd1
5 changed files with 75 additions and 9 deletions

View File

@ -1367,7 +1367,8 @@ crypto_bdev_ch_destroy_cb(void *io_device, void *ctx_buf)
* on the global list. */
static int
vbdev_crypto_insert_name(const char *bdev_name, const char *vbdev_name,
const char *crypto_pmd, const char *key)
const char *crypto_pmd, const char *key,
const char *cipher, const char *key2)
{
struct bdev_names *name;
int rc, j;
@ -1452,14 +1453,15 @@ error_alloc_bname:
/* RPC entry point for crypto creation. */
int
create_crypto_disk(const char *bdev_name, const char *vbdev_name,
const char *crypto_pmd, const char *key)
const char *crypto_pmd, const char *key,
const char *cipher, const char *key2)
{
struct spdk_bdev *bdev = NULL;
int rc = 0;
bdev = spdk_bdev_get_by_name(bdev_name);
rc = vbdev_crypto_insert_name(bdev_name, vbdev_name, crypto_pmd, key);
rc = vbdev_crypto_insert_name(bdev_name, vbdev_name, crypto_pmd, key, cipher, key2);
if (rc) {
return rc;
}
@ -1490,6 +1492,8 @@ vbdev_crypto_init(void)
int i;
int rc = 0;
const char *key = NULL;
const char *cipher = NULL;
const char *key2 = NULL;
/* Fully configure both SW and HW drivers. */
rc = vbdev_crypto_init_crypto_drivers();
@ -1534,8 +1538,16 @@ vbdev_crypto_init(void)
return -EINVAL;
}
/* These are optional. */
cipher = spdk_conf_section_get_nmval(sp, "CRY", i, 4);
if (cipher == NULL) {
cipher = AES_CBC;
}
key2 = spdk_conf_section_get_nmval(sp, "CRY", i, 5);
/* Note: config file options do not support QAT AES_XTS, use RPC */
rc = vbdev_crypto_insert_name(conf_bdev_name, conf_vbdev_name,
crypto_pmd, key);
crypto_pmd, key, cipher, key2);
if (rc != 0) {
return rc;
}

View File

@ -44,6 +44,10 @@
#define AESNI_MB "crypto_aesni_mb"
#define QAT "crypto_qat"
/* Supported ciphers */
#define AES_CBC "AES_CBC" /* QAT and AESNI_MB */
#define AES_XTS "AES_XTS" /* QAT only */
typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno);
/**
@ -53,10 +57,13 @@ typedef void (*spdk_delete_crypto_complete)(void *cb_arg, int bdeverrno);
* \param vbdev_name Name of the new crypto vbdev.
* \param crypto_pmd Name of the polled mode driver to use for this vbdev.
* \param key The key to use for this vbdev.
* \param cipher The cipher to use for this vbdev.
* \param keys The 2nd key to use for AES_XTS cipher.
* \return 0 on success, other on failure.
*/
int create_crypto_disk(const char *bdev_name, const char *vbdev_name,
const char *crypto_pmd, const char *key);
const char *crypto_pmd, const char *key,
const char *cipher, const char *key2);
/**
* Delete crypto bdev.

View File

@ -39,6 +39,8 @@ struct rpc_construct_crypto {
char *name;
char *crypto_pmd;
char *key;
char *cipher;
char *key2;
};
/* Free the allocated memory resource after the RPC handling. */
@ -49,6 +51,8 @@ free_rpc_construct_crypto(struct rpc_construct_crypto *r)
free(r->name);
free(r->crypto_pmd);
free(r->key);
free(r->cipher);
free(r->key2);
}
/* Structure to decode the input parameters for this RPC method. */
@ -57,6 +61,8 @@ static const struct spdk_json_object_decoder rpc_construct_crypto_decoders[] = {
{"name", offsetof(struct rpc_construct_crypto, name), spdk_json_decode_string},
{"crypto_pmd", offsetof(struct rpc_construct_crypto, crypto_pmd), spdk_json_decode_string},
{"key", offsetof(struct rpc_construct_crypto, key), spdk_json_decode_string},
{"cipher", offsetof(struct rpc_construct_crypto, cipher), spdk_json_decode_string, true},
{"key2", offsetof(struct rpc_construct_crypto, key2), spdk_json_decode_string, true},
};
/* Decode the parameters for this RPC method and properly construct the crypto
@ -78,8 +84,42 @@ spdk_rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
goto cleanup;
}
if (req.cipher == NULL) {
req.cipher = strdup(AES_CBC);
if (req.cipher == NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"Unable to allocate memory for req.cipher");
goto cleanup;
}
}
if (strcmp(req.cipher, AES_XTS) != 0 && strcmp(req.cipher, AES_CBC) != 0) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid cipher: %s",
req.cipher);
goto cleanup;
}
if (strcmp(req.crypto_pmd, AESNI_MB) == 0 && strcmp(req.cipher, AES_XTS) == 0) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid cipher. AES_XTS is only available on QAT.");
goto cleanup;
}
if (strcmp(req.cipher, AES_XTS) == 0 && req.key2 == NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid key. A 2nd key is needed for AES_XTS.");
goto cleanup;
}
if (strcmp(req.cipher, AES_CBC) == 0 && req.key2 != NULL) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Invalid key. A 2nd key is needed only for AES_XTS.");
goto cleanup;
}
rc = create_crypto_disk(req.base_bdev_name, req.name,
req.crypto_pmd, req.key);
req.crypto_pmd, req.key, req.cipher, req.key2);
if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;

View File

@ -195,13 +195,17 @@ if __name__ == "__main__":
base_bdev_name=args.base_bdev_name,
name=args.name,
crypto_pmd=args.crypto_pmd,
key=args.key))
key=args.key,
cipher=args.cipher,
key2=args.key2))
p = subparsers.add_parser('bdev_crypto_create', aliases=['construct_crypto_bdev'],
help='Add a crypto vbdev')
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('crypto_pmd', help="Name of the crypto device driver")
p.add_argument('key', help="Key")
p.add_argument('-c', '--cipher', help="cipher to use, AES_CBC or AES_XTS (QAT only)", default="AES_CBC")
p.add_argument('-k2', '--key2', help="2nd key for cipher AET_XTS", default=None)
p.set_defaults(func=bdev_crypto_create)
def bdev_crypto_delete(args):

View File

@ -74,7 +74,7 @@ def bdev_compress_get_orphans(client, name=None):
@deprecated_alias('construct_crypto_bdev')
def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd, key):
def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd, key, cipher=None, key2=None):
"""Construct a crypto virtual block device.
Args:
@ -87,7 +87,10 @@ def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd, key):
Name of created virtual block device.
"""
params = {'base_bdev_name': base_bdev_name, 'name': name, 'crypto_pmd': crypto_pmd, 'key': key}
if cipher:
params['cipher'] = cipher
if key2:
params['key2'] = key2
return client.call('bdev_crypto_create', params)