Commit f070b78c authored by paul luse's avatar paul luse Committed by Tomasz Zawadzki
Browse files

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



Signed-off-by: default avatarpaul luse <paul.e.luse@intel.com>
Change-Id: Iadd03f8da305e97e3f1d57ef4aeaece400e8d959
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/441


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 9e1b82ac
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -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;
		}
+8 −1
Original line number Diff line number Diff line
@@ -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.
+41 −1
Original line number Diff line number Diff line
@@ -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;
+5 −1
Original line number Diff line number Diff line
@@ -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):
+5 −2
Original line number Diff line number Diff line
@@ -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)