From f241068fcaca0e6a00f0c61bca3b07d10744d40b Mon Sep 17 00:00:00 2001 From: paul luse Date: Fri, 31 Jan 2020 22:31:37 +0000 Subject: [PATCH] module/crypto: add AES_XTS support for QAT pmd Tests are coming in next patch... Signed-off-by: paul luse Change-Id: I8b9c80f3ea1d3f59006f802840da52c3c8c46167 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/442 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Aleksey Marchuk --- CHANGELOG.md | 7 ++++ module/bdev/crypto/vbdev_crypto.c | 59 +++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27feca7f0..ee0a72d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,13 @@ library through the `spdk_vmd_init` call. `--json-ignore-init-errors` command line param has been added to ignore initialization errors on JSON config load. +### crypto + +Support for AES_XTS was added for the QAT polled mode driver (pmd). The create RPC +`bdev_crypto_create` has 2 new optional parameters: cipher and key2. Cipher can be either +AES_CBC (default) or AES_XTS. AES_XTS isonly valid when using the QAT polled mode driver. +The key2 parameter is the second key required for AES_XTS. + ## v20.01 ### bdev diff --git a/module/bdev/crypto/vbdev_crypto.c b/module/bdev/crypto/vbdev_crypto.c index c43609bd3..c397b9327 100644 --- a/module/bdev/crypto/vbdev_crypto.c +++ b/module/bdev/crypto/vbdev_crypto.c @@ -130,6 +130,7 @@ uint8_t g_number_of_claimed_volumes = 0; /* Specific to AES_CBC. */ #define AES_CBC_IV_LENGTH 16 #define AES_CBC_KEY_LENGTH 16 +#define AES_XTS_KEY_LENGTH 16 /* XTS uses 2 keys, each of this size. */ /* Common for suported devices. */ #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ @@ -153,6 +154,8 @@ struct bdev_names { */ uint8_t *key; /* key per bdev */ char *drv_name; /* name of the crypto device driver */ + char *cipher; /* AES_CBC or AES_XTS */ + uint8_t *key2; /* key #2 for AES_XTS, per bdev */ TAILQ_ENTRY(bdev_names) link; }; static TAILQ_HEAD(, bdev_names) g_bdev_names = TAILQ_HEAD_INITIALIZER(g_bdev_names); @@ -1431,11 +1434,40 @@ vbdev_crypto_insert_name(const char *bdev_name, const char *vbdev_name, goto error_invalid_key; } + if (strncmp(cipher, AES_XTS, sizeof(AES_XTS)) == 0) { + /* To please scan-build, input validation makes sure we can't + * have this cipher without providing a key2. + */ + name->cipher = AES_XTS; + assert(key2); + if (strnlen(key2, (AES_XTS_KEY_LENGTH + 1)) != AES_XTS_KEY_LENGTH) { + SPDK_ERRLOG("invalid AES_XTS key length\n"); + rc = -EINVAL; + goto error_invalid_key2; + } + + name->key2 = strdup(key2); + if (!name->key2) { + SPDK_ERRLOG("could not allocate name->key2\n"); + rc = -ENOMEM; + goto error_alloc_key2; + } + } else if (strncmp(cipher, AES_CBC, sizeof(AES_CBC)) == 0) { + name->cipher = AES_CBC; + } else { + SPDK_ERRLOG("Invalid cipher: %s\n", cipher); + rc = -EINVAL; + goto error_cipher; + } + TAILQ_INSERT_TAIL(&g_bdev_names, name, link); return 0; /* Error cleanup paths. */ +error_alloc_key2: +error_invalid_key2: +error_cipher: error_invalid_key: free(name->key); error_alloc_key: @@ -1572,6 +1604,7 @@ vbdev_crypto_finish(void) free(name->key); free(name->bdev_name); free(name->vbdev_name); + free(name->key2); free(name); } @@ -1690,6 +1723,7 @@ vbdev_crypto_claim(struct spdk_bdev *bdev) struct vbdev_dev *device; bool found = false; int rc = 0; + void *tmp = NULL; if (g_number_of_claimed_volumes >= MAX_CRYPTO_VOLUMES) { SPDK_DEBUGLOG(SPDK_LOG_CRYPTO, "Reached max number of claimed volumes\n"); @@ -1744,6 +1778,20 @@ vbdev_crypto_claim(struct spdk_bdev *bdev) spdk_max(spdk_u32log2(bdev->blocklen), bdev->required_alignment); SPDK_NOTICELOG("QAT in use: Required alignment set to %u\n", vbdev->crypto_bdev.required_alignment); + if (strcmp(name->cipher, AES_CBC) == 0) { + SPDK_NOTICELOG("QAT using cipher: AES_CBC\n"); + } else { + SPDK_NOTICELOG("QAT using cipher: AES_XTS\n"); + /* DPDK expects they keys to be concatenated together. */ + tmp = realloc(vbdev->key, (AES_XTS_KEY_LENGTH * 2) + 1); + if (tmp == NULL) { + SPDK_ERRLOG("could not reallocate memory for XTS keys\n"); + rc = -ENOMEM; + goto error_key_realloc; + } + vbdev->key = tmp; + memcpy(vbdev->key + AES_XTS_KEY_LENGTH, name->key2, AES_XTS_KEY_LENGTH + 1); + } } else { vbdev->crypto_bdev.required_alignment = bdev->required_alignment; } @@ -1816,8 +1864,13 @@ vbdev_crypto_claim(struct spdk_bdev *bdev) vbdev->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; vbdev->cipher_xform.cipher.key.data = vbdev->key; vbdev->cipher_xform.cipher.iv.offset = IV_OFFSET; - vbdev->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; - vbdev->cipher_xform.cipher.key.length = AES_CBC_KEY_LENGTH; + if (strcmp(name->cipher, AES_CBC) == 0) { + vbdev->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; + vbdev->cipher_xform.cipher.key.length = AES_CBC_KEY_LENGTH; + } else { + vbdev->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_XTS; + vbdev->cipher_xform.cipher.key.length = AES_XTS_KEY_LENGTH * 2; + } vbdev->cipher_xform.cipher.iv.length = AES_CBC_IV_LENGTH; vbdev->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; @@ -1867,6 +1920,7 @@ error_open: TAILQ_REMOVE(&g_vbdev_crypto, vbdev, link); spdk_io_device_unregister(vbdev, NULL); free(vbdev->drv_name); +error_key_realloc: error_drv_name: free(vbdev->key); error_alloc_key: @@ -1901,6 +1955,7 @@ delete_crypto_disk(struct spdk_bdev *bdev, spdk_delete_crypto_complete cb_fn, free(name->vbdev_name); free(name->drv_name); free(name->key); + free(name->key2); free(name); break; }