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. */ * on the global list. */
static int static int
vbdev_crypto_insert_name(const char *bdev_name, const char *vbdev_name, 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; struct bdev_names *name;
int rc, j; int rc, j;
@ -1452,14 +1453,15 @@ error_alloc_bname:
/* RPC entry point for crypto creation. */ /* RPC entry point for crypto creation. */
int int
create_crypto_disk(const char *bdev_name, const char *vbdev_name, 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; struct spdk_bdev *bdev = NULL;
int rc = 0; int rc = 0;
bdev = spdk_bdev_get_by_name(bdev_name); 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) { if (rc) {
return rc; return rc;
} }
@ -1490,6 +1492,8 @@ vbdev_crypto_init(void)
int i; int i;
int rc = 0; int rc = 0;
const char *key = NULL; const char *key = NULL;
const char *cipher = NULL;
const char *key2 = NULL;
/* Fully configure both SW and HW drivers. */ /* Fully configure both SW and HW drivers. */
rc = vbdev_crypto_init_crypto_drivers(); rc = vbdev_crypto_init_crypto_drivers();
@ -1534,8 +1538,16 @@ vbdev_crypto_init(void)
return -EINVAL; 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, rc = vbdev_crypto_insert_name(conf_bdev_name, conf_vbdev_name,
crypto_pmd, key); crypto_pmd, key, cipher, key2);
if (rc != 0) { if (rc != 0) {
return rc; return rc;
} }

View File

@ -44,6 +44,10 @@
#define AESNI_MB "crypto_aesni_mb" #define AESNI_MB "crypto_aesni_mb"
#define QAT "crypto_qat" #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); 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 vbdev_name Name of the new crypto vbdev.
* \param crypto_pmd Name of the polled mode driver to use for this 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 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. * \return 0 on success, other on failure.
*/ */
int create_crypto_disk(const char *bdev_name, const char *vbdev_name, 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. * Delete crypto bdev.

View File

@ -39,6 +39,8 @@ struct rpc_construct_crypto {
char *name; char *name;
char *crypto_pmd; char *crypto_pmd;
char *key; char *key;
char *cipher;
char *key2;
}; };
/* Free the allocated memory resource after the RPC handling. */ /* 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->name);
free(r->crypto_pmd); free(r->crypto_pmd);
free(r->key); free(r->key);
free(r->cipher);
free(r->key2);
} }
/* Structure to decode the input parameters for this RPC method. */ /* 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}, {"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},
{"key", offsetof(struct rpc_construct_crypto, key), 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 /* 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; 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, 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) { if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup; goto cleanup;

View File

@ -195,13 +195,17 @@ if __name__ == "__main__":
base_bdev_name=args.base_bdev_name, base_bdev_name=args.base_bdev_name,
name=args.name, name=args.name,
crypto_pmd=args.crypto_pmd, 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'], p = subparsers.add_parser('bdev_crypto_create', aliases=['construct_crypto_bdev'],
help='Add a crypto vbdev') 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('crypto_pmd', help="Name of the crypto device driver")
p.add_argument('key', help="Key") 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) p.set_defaults(func=bdev_crypto_create)
def bdev_crypto_delete(args): def bdev_crypto_delete(args):

View File

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