Commit 6ab03dae authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Konrad Sztyber
Browse files

lib/mlx5: Update keytag creation to use PRM



The new way to create DEKs is not compatible with
mlx5dv API used by accel_mlx5, so both methods of creating
DEKs remain in this patch. Legacy way will be removed soon.

Signed-off-by: default avatarAlexey Marchuk <alexeymar@nvidia.com>
Change-Id: I7be82f6ec6cbacc56ab1482537a806792a7e2a77
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23107


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent 8ffbc77d
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -25,7 +25,9 @@
 * DEK - Data Encryption Key
 */

struct spdk_mlx5_crypto_dek;
#define SPDK_MLX5_VENDOR_ID_MELLANOX 0x2c9

struct spdk_mlx5_crypto_dek_legacy;
struct spdk_mlx5_crypto_keytag;

enum {
@@ -134,6 +136,13 @@ enum spdk_mlx5_crypto_key_tweak_mode {
	SPDK_MLX5_CRYPTO_KEY_TWEAK_MODE_SIMPLE_LBA_LE	= 1,
};

struct spdk_mlx5_crypto_dek_data {
	/** low level devx obj id which represents the DEK */
	uint32_t dek_obj_id;
	/** Crypto key tweak mode */
	enum spdk_mlx5_crypto_key_tweak_mode tweak_mode;
};

struct spdk_mlx5_umr_crypto_attr {
	uint8_t enc_order; /* see \ref enum spdk_mlx5_encryption_order */
	uint8_t bs_selector; /* see \ref enum spdk_mlx5_block_size_selector */
@@ -317,7 +326,7 @@ int spdk_mlx5_crypto_keytag_create(struct spdk_mlx5_crypto_dek_create_attr *attr
void spdk_mlx5_crypto_keytag_destroy(struct spdk_mlx5_crypto_keytag *keytag);

/**
 * Fills attributes used to register UMR with crypto operation
 * Fills attributes used to register UMR with crypto operation. Deprecated
 *
 * \param attr_out Configured UMR attributes
 * \param keytag Keytag with DEKs
@@ -331,6 +340,18 @@ int spdk_mlx5_crypto_set_attr(struct mlx5dv_crypto_attr *attr_out,
			      struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd,
			      uint32_t block_size, uint64_t iv, bool encrypt_on_tx);

/**
 * Get Data Encryption Key data
 *
 * \param keytag Keytag with DEKs
 * \param pd Protection Domain which is going to be used to register UMR.
 * \param dek_obj_id Low level DEK ID, can be used to configure crypto UMR
 * \param data DEK data to be filled by this function
 * \return 0 on success, negated errno on failure
 */
int spdk_mlx5_crypto_get_dek_data(struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd,
				  struct spdk_mlx5_crypto_dek_data *data);

/**
 * Specify which devices are allowed to be used for crypto operation.
 *
+244 −54
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@
#include "spdk_internal/mlx5.h"
#include "spdk_internal/rdma_utils.h"
#include "mlx5_ifc.h"

#define MLX5_VENDOR_ID_MELLANOX 0x2c9
#include "mlx5_priv.h"

/* Plaintext key sizes */
/* 64b keytag */
@@ -29,22 +28,46 @@
/* key1_256b + key2_256b + 64b_keytag */
#define SPDK_MLX5_AES_XTS_256_DEK_BYTES_WITH_KEYTAG (SPDK_MLX5_AES_XTS_256_DEK_BYTES + SPDK_MLX5_AES_XTS_KEYTAG_SIZE)

static char **g_allowed_devices;
static size_t g_allowed_devices_count;
struct mlx5_crypto_dek_init_attr {
	char *dek;
	uint64_t opaque;
	uint32_t key_size_bytes;
	uint8_t key_size; /* driver representation of \b key_size_bytes */
	uint8_t keytag;
};

struct spdk_mlx5_crypto_dek {
struct mlx5_crypto_dek_query_attr {
	/* state either MLX5_ENCRYPTION_KEY_OBJ_STATE_READY or MLX5_ENCRYPTION_KEY_OBJ_STATE_ERROR */
	uint8_t state;
	uint64_t opaque;
};

struct spdk_mlx5_crypto_dek_legacy {
	struct mlx5dv_dek *dek_obj;
	struct ibv_pd *pd;
	struct ibv_context *context;
};

struct mlx5_crypto_dek {
	struct mlx5dv_devx_obj *devx_obj;
	struct ibv_pd *pd;
	struct ibv_context *context;
	/* Cached dek_obj_id */
	uint32_t dek_obj_id;
	enum spdk_mlx5_crypto_key_tweak_mode tweak_mode;
};

struct spdk_mlx5_crypto_keytag {
	struct spdk_mlx5_crypto_dek *deks;
	struct mlx5_crypto_dek *deks;
	struct spdk_mlx5_crypto_dek_legacy *deks_legacy;
	uint32_t deks_num;
	bool has_keytag;
	char keytag[8];
};

static char **g_allowed_devices;
static size_t g_allowed_devices_count;

static void
mlx5_crypto_devs_free(void)
{
@@ -140,7 +163,7 @@ spdk_mlx5_crypto_devs_get(int *dev_num)
			SPDK_ERRLOG("Failed to query dev %s, skipping\n", dev->device->name);
			continue;
		}
		if (dev_attr.vendor_id != MLX5_VENDOR_ID_MELLANOX) {
		if (dev_attr.vendor_id != SPDK_MLX5_VENDOR_ID_MELLANOX) {
			SPDK_DEBUGLOG(mlx5, "dev %s is not Mellanox device, skipping\n", dev->device->name);
			continue;
		}
@@ -275,10 +298,21 @@ spdk_mlx5_device_query_caps(struct ibv_context *context, struct spdk_mlx5_device
	return 0;
}

static void
mlx5_crypto_dek_deinit(struct mlx5_crypto_dek *dek)
{
	int rc;

	rc = mlx5dv_devx_obj_destroy(dek->devx_obj);
	if (rc) {
		SPDK_ERRLOG("Failed to destroy crypto obj:%p, rc %d\n", dek->devx_obj, rc);
	}
}

void
spdk_mlx5_crypto_keytag_destroy(struct spdk_mlx5_crypto_keytag *keytag)
{
	struct spdk_mlx5_crypto_dek *dek;
	struct mlx5_crypto_dek *dek;
	uint32_t i;

	if (!keytag) {
@@ -287,53 +321,159 @@ spdk_mlx5_crypto_keytag_destroy(struct spdk_mlx5_crypto_keytag *keytag)

	for (i = 0; i < keytag->deks_num; i++) {
		dek = &keytag->deks[i];
		if (dek->dek_obj) {
			mlx5dv_dek_destroy(dek->dek_obj);
		if (dek->devx_obj) {
			mlx5_crypto_dek_deinit(dek);
		}
		if (dek->pd) {
			spdk_rdma_utils_put_pd(dek->pd);
		}

		if (keytag->deks_legacy[i].dek_obj) {
			mlx5dv_dek_destroy(keytag->deks_legacy[i].dek_obj);
		}

	}
	spdk_memset_s(keytag->keytag, sizeof(keytag->keytag), 0, sizeof(keytag->keytag));
	free(keytag->deks_legacy);
	free(keytag->deks);
	free(keytag);
}

static int
mlx5_crypto_dek_init(struct ibv_pd *pd, struct mlx5_crypto_dek_init_attr *attr,
		     struct mlx5_crypto_dek *dek)
{
	uint32_t in[DEVX_ST_SZ_DW(create_encryption_key_obj_in)] = {};
	uint32_t out[DEVX_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
	uint8_t *dek_in;
	uint32_t pdn;
	int rc;

	rc = mlx5_get_pd_id(pd, &pdn);
	if (rc) {
		return rc;
	}

	dek_in = DEVX_ADDR_OF(create_encryption_key_obj_in, in, hdr);
	DEVX_SET(general_obj_in_cmd_hdr, dek_in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
	DEVX_SET(general_obj_in_cmd_hdr, dek_in, obj_type, MLX5_OBJ_TYPE_DEK);
	dek_in = DEVX_ADDR_OF(create_encryption_key_obj_in, in, key_obj);
	DEVX_SET(encryption_key_obj, dek_in, key_size, attr->key_size);
	DEVX_SET(encryption_key_obj, dek_in, has_keytag, attr->keytag);
	DEVX_SET(encryption_key_obj, dek_in, key_purpose, MLX5_ENCRYPTION_KEY_OBJ_KEY_PURPOSE_AES_XTS);
	DEVX_SET(encryption_key_obj, dek_in, pd, pdn);
	memcpy(DEVX_ADDR_OF(encryption_key_obj, dek_in, opaque), &attr->opaque, sizeof(attr->opaque));
	memcpy(DEVX_ADDR_OF(encryption_key_obj, dek_in, key), attr->dek, attr->key_size_bytes);

	dek->devx_obj = mlx5dv_devx_obj_create(pd->context, in, sizeof(in), out, sizeof(out));
	spdk_memset_s(DEVX_ADDR_OF(encryption_key_obj, dek_in, key), attr->key_size_bytes, 0,
		      attr->key_size_bytes);
	if (!dek->devx_obj) {
		return -errno;
	}
	dek->dek_obj_id = DEVX_GET(general_obj_out_cmd_hdr, out, obj_id);

	return 0;
}

static int
mlx5_crypto_dek_query(struct mlx5_crypto_dek *dek, struct mlx5_crypto_dek_query_attr *attr)
{
	uint32_t out[DEVX_ST_SZ_DW(query_encryption_key_obj_out)] = {};
	uint32_t in[DEVX_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
	uint8_t *dek_out;
	int rc;

	assert(attr);
	DEVX_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
	DEVX_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_DEK);
	DEVX_SET(general_obj_in_cmd_hdr, in, obj_id, dek->dek_obj_id);

	rc = mlx5dv_devx_obj_query(dek->devx_obj, in, sizeof(in), out, sizeof(out));
	if (rc) {
		return rc;
	}

	dek_out = DEVX_ADDR_OF(query_encryption_key_obj_out, out, obj);
	attr->state = DEVX_GET(encryption_key_obj, dek_out, state);
	memcpy(&attr->opaque, DEVX_ADDR_OF(encryption_key_obj, dek_out, opaque), sizeof(attr->opaque));

	return 0;
}

static int
mlx5_crypto_dek_create_legacy(struct spdk_mlx5_crypto_dek_legacy *dek,
			      struct mlx5dv_dek_init_attr *init_attr_legacy)
{
	struct mlx5dv_dek_attr query_attr_legacy;
	int rc;

	init_attr_legacy->pd = dek->pd;

	dek->dek_obj = mlx5dv_dek_create(dek->context, init_attr_legacy);
	if (!dek->dek_obj) {
		SPDK_ERRLOG("mlx5dv_dek_create failed on dev %s, errno %d\n", dek->context->device->name, errno);
		return -EINVAL;
	}

	rc = mlx5dv_dek_query(dek->dek_obj, &query_attr_legacy);
	if (rc) {
		SPDK_ERRLOG("Failed to query DEK on dev %s, rc %d\n", dek->context->device->name, rc);
		return rc;
	}
	if (query_attr_legacy.state != MLX5DV_DEK_STATE_READY) {
		SPDK_ERRLOG("DEK on dev %s state %d\n", dek->context->device->name, query_attr_legacy.state);
		return -EINVAL;
	}

	return 0;
}

int
spdk_mlx5_crypto_keytag_create(struct spdk_mlx5_crypto_dek_create_attr *attr,
			       struct spdk_mlx5_crypto_keytag **out)
{
	struct spdk_mlx5_crypto_dek *dek;
	struct mlx5_crypto_dek *dek;
	struct spdk_mlx5_crypto_keytag *keytag;
	struct ibv_context **devs;
	struct mlx5dv_dek_init_attr init_attr = {};
	struct mlx5dv_dek_attr query_attr;
	struct ibv_pd *pd;
	struct mlx5_crypto_dek_init_attr dek_attr = {};
	struct mlx5_crypto_dek_query_attr query_attr;
	struct mlx5dv_dek_init_attr init_attr_legacy = {};
	struct spdk_mlx5_crypto_dek_legacy *dek_legacy;
	struct spdk_mlx5_device_caps dev_caps;
	int num_devs = 0, i, rc;
	bool has_keytag;


	if (!attr || !attr->dek) {
		return -EINVAL;
	}
	switch (attr->dek_len) {
	dek_attr.dek = attr->dek;
	dek_attr.key_size_bytes = attr->dek_len;
	dek_attr.opaque = 0;
	switch (dek_attr.key_size_bytes) {
	case SPDK_MLX5_AES_XTS_128_DEK_BYTES_WITH_KEYTAG:
		init_attr.key_size = MLX5DV_CRYPTO_KEY_SIZE_128;
		has_keytag = true;
		init_attr_legacy.key_size = MLX5DV_CRYPTO_KEY_SIZE_128;
		init_attr_legacy.has_keytag = true;
		dek_attr.key_size = MLX5_ENCRYPTION_KEY_OBJ_KEY_SIZE_SIZE_128;
		dek_attr.keytag = 1;
		SPDK_DEBUGLOG(mlx5, "128b AES_XTS with keytag\n");
		break;
	case SPDK_MLX5_AES_XTS_256_DEK_BYTES_WITH_KEYTAG:
		init_attr.key_size = MLX5DV_CRYPTO_KEY_SIZE_256;
		has_keytag = true;
		init_attr_legacy.key_size = MLX5DV_CRYPTO_KEY_SIZE_256;
		init_attr_legacy.has_keytag = true;
		dek_attr.key_size = MLX5_ENCRYPTION_KEY_OBJ_KEY_SIZE_SIZE_256;
		dek_attr.keytag = 1;
		SPDK_DEBUGLOG(mlx5, "256b AES_XTS with keytag\n");
		break;
	case SPDK_MLX5_AES_XTS_128_DEK_BYTES:
		init_attr.key_size = MLX5DV_CRYPTO_KEY_SIZE_128;
		has_keytag = false;
		init_attr_legacy.key_size = MLX5DV_CRYPTO_KEY_SIZE_128;
		init_attr_legacy.has_keytag = false;
		dek_attr.key_size = MLX5_ENCRYPTION_KEY_OBJ_KEY_SIZE_SIZE_128;
		dek_attr.keytag = 0;
		SPDK_DEBUGLOG(mlx5, "128b AES_XTS\n");
		break;
	case SPDK_MLX5_AES_XTS_256_DEK_BYTES:
		init_attr.key_size = MLX5DV_CRYPTO_KEY_SIZE_256;
		has_keytag = false;
		init_attr_legacy.key_size = MLX5DV_CRYPTO_KEY_SIZE_256;
		init_attr_legacy.has_keytag = false;
		dek_attr.key_size = MLX5_ENCRYPTION_KEY_OBJ_KEY_SIZE_SIZE_256;
		dek_attr.keytag = 0;
		SPDK_DEBUGLOG(mlx5, "256b AES_XTS\n");
		break;
	default:
@@ -342,7 +482,7 @@ spdk_mlx5_crypto_keytag_create(struct spdk_mlx5_crypto_dek_create_attr *attr,
			    "256b key + key2, %u bytes\n"
			    "128b key + key2 + keytag, %u bytes\n"
			    "256b lye + key2 + keytag, %u bytes\n",
			    attr->dek_len, SPDK_MLX5_AES_XTS_128_DEK_BYTES, MLX5DV_CRYPTO_KEY_SIZE_256,
			    attr->dek_len, SPDK_MLX5_AES_XTS_128_DEK_BYTES, SPDK_MLX5_AES_XTS_256_DEK_BYTES,
			    SPDK_MLX5_AES_XTS_128_DEK_BYTES_WITH_KEYTAG, SPDK_MLX5_AES_XTS_256_DEK_BYTES_WITH_KEYTAG);
		return -EINVAL;
	}
@@ -359,7 +499,7 @@ spdk_mlx5_crypto_keytag_create(struct spdk_mlx5_crypto_dek_create_attr *attr,
		spdk_mlx5_crypto_devs_release(devs);
		return -ENOMEM;
	}
	keytag->deks = calloc(num_devs, sizeof(struct spdk_mlx5_crypto_dek));
	keytag->deks = calloc(num_devs, sizeof(struct mlx5_crypto_dek));
	if (!keytag->deks) {
		SPDK_ERRLOG("Memory allocation failed\n");
		spdk_mlx5_crypto_devs_release(devs);
@@ -367,46 +507,73 @@ spdk_mlx5_crypto_keytag_create(struct spdk_mlx5_crypto_dek_create_attr *attr,
		return -ENOMEM;
	}

	/* Legacy part, to be removed soon */
	memcpy(init_attr_legacy.key, attr->dek, attr->dek_len);
	keytag->deks_legacy = calloc(num_devs, sizeof(struct spdk_mlx5_crypto_dek_legacy));
	if (!keytag->deks_legacy) {
		SPDK_ERRLOG("Memory allocation failed\n");
		spdk_mlx5_crypto_devs_release(devs);
		free(keytag->deks);
		free(keytag);
		return -ENOMEM;
	}
	init_attr_legacy.key_purpose = MLX5DV_CRYPTO_KEY_PURPOSE_AES_XTS;
	init_attr_legacy.comp_mask = MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN;
	init_attr_legacy.crypto_login = NULL;

	for (i = 0; i < num_devs; i++) {
		keytag->deks_num++;
		dek = &keytag->deks[i];
		dek->pd = spdk_rdma_utils_get_pd(devs[i]);
		if (!dek->pd) {
		pd = spdk_rdma_utils_get_pd(devs[i]);
		if (!pd) {
			SPDK_ERRLOG("Failed to get PD on device %s\n", devs[i]->device->name);
			rc = -EINVAL;
			goto err_out;
		}
		dek->context = devs[i];

		init_attr.pd = dek->pd;
		init_attr.has_keytag = has_keytag;
		init_attr.key_purpose = MLX5DV_CRYPTO_KEY_PURPOSE_AES_XTS;
		init_attr.comp_mask = MLX5DV_DEK_INIT_ATTR_CRYPTO_LOGIN;
		init_attr.crypto_login = NULL;
		memcpy(init_attr.key, attr->dek, attr->dek_len);

		dek->dek_obj = mlx5dv_dek_create(dek->context, &init_attr);
		spdk_memset_s(init_attr.key, sizeof(init_attr.key), 0, sizeof(init_attr.key));
		if (!dek->dek_obj) {
			SPDK_ERRLOG("mlx5dv_dek_create failed on dev %s, errno %d\n", dek->context->device->name, errno);
			rc = -EINVAL;
		memset(&dev_caps, 0, sizeof(dev_caps));
		rc =  spdk_mlx5_device_query_caps(devs[i], &dev_caps);
		if (rc) {
			SPDK_ERRLOG("Failed to get device %s crypto caps\n", devs[i]->device->name);
			goto err_out;
		}
		rc = mlx5_crypto_dek_init(pd, &dek_attr, dek);
		if (rc) {
			SPDK_ERRLOG("Failed to create DEK on dev %s, rc %d\n", pd->context->device->name, rc);
			goto err_out;
		}

		memset(&query_attr, 0, sizeof(query_attr));
		rc = mlx5dv_dek_query(dek->dek_obj, &query_attr);
		rc = mlx5_crypto_dek_query(dek, &query_attr);
		if (rc) {
			SPDK_ERRLOG("Failed to query DEK on dev %s, rc %d\n", dek->context->device->name, rc);
			SPDK_ERRLOG("Failed to query DEK on dev %s, rc %d\n", pd->context->device->name, rc);
			goto err_out;
		}
		if (query_attr.state != MLX5DV_DEK_STATE_READY) {
			SPDK_ERRLOG("DEK on dev %s state %d\n", dek->context->device->name, query_attr.state);
		if (query_attr.opaque != 0 || query_attr.state != MLX5_ENCRYPTION_KEY_OBJ_STATE_READY) {
			SPDK_ERRLOG("DEK on dev %s in bad state %d, oapque %"PRIu64"\n", pd->context->device->name,
				    query_attr.state, query_attr.opaque);
			rc = -EINVAL;
			goto err_out;
		}

		dek->pd = pd;
		dek->context = devs[i];
		dek->tweak_mode = dev_caps.crypto.multi_block_be_tweak ?
				  SPDK_MLX5_CRYPTO_KEY_TWEAK_MODE_SIMPLE_LBA_BE : SPDK_MLX5_CRYPTO_KEY_TWEAK_MODE_SIMPLE_LBA_LE;

		/* Legacy part, to be removed soon */
		dek_legacy = &keytag->deks_legacy[i];
		dek_legacy->pd = pd;
		dek_legacy->context = devs[i];
		rc = mlx5_crypto_dek_create_legacy(dek_legacy, &init_attr_legacy);
		if (rc) {
			SPDK_ERRLOG("Failed to create legacy DEK on dev %s, rc %d\n", pd->context->device->name, rc);
			goto err_out;
		}
	}

	if (has_keytag) {
	spdk_memset_s(init_attr_legacy.key, sizeof(init_attr_legacy.key), 0, sizeof(init_attr_legacy.key));

	if (dek_attr.keytag) {
		/* Save keytag, it will be used to configure crypto MKEY */
		keytag->has_keytag = true;
		memcpy(keytag->keytag, attr->dek + attr->dek_len - SPDK_MLX5_AES_XTS_KEYTAG_SIZE,
@@ -425,10 +592,10 @@ err_out:
	return rc;
}

static inline struct spdk_mlx5_crypto_dek *
static inline struct mlx5_crypto_dek *
mlx5_crypto_get_dek_by_pd(struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd)
{
	struct spdk_mlx5_crypto_dek *dek;
	struct mlx5_crypto_dek *dek;
	uint32_t i;

	for (i = 0; i < keytag->deks_num; i++) {
@@ -446,10 +613,16 @@ spdk_mlx5_crypto_set_attr(struct mlx5dv_crypto_attr *attr_out,
			  struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd,
			  uint32_t block_size, uint64_t iv, bool encrypt_on_tx)
{
	struct spdk_mlx5_crypto_dek *dek;
	struct spdk_mlx5_crypto_dek_legacy *dek = NULL;
	enum mlx5dv_block_size bs;
	uint32_t i;

	dek = mlx5_crypto_get_dek_by_pd(keytag, pd);
	for (i = 0; i < keytag->deks_num; i++) {
		if (keytag->deks_legacy[i].pd == pd) {
			dek = &keytag->deks_legacy[i];
			break;
		}
	}
	if (spdk_unlikely(!dek)) {
		SPDK_ERRLOG("No DEK for pd %p (dev %s)\n", pd, pd->context->device->name);
		return -EINVAL;
@@ -489,4 +662,21 @@ spdk_mlx5_crypto_set_attr(struct mlx5dv_crypto_attr *attr_out,
	return 0;
}

int
spdk_mlx5_crypto_get_dek_data(struct spdk_mlx5_crypto_keytag *keytag, struct ibv_pd *pd,
			      struct spdk_mlx5_crypto_dek_data *data)
{
	struct mlx5_crypto_dek *dek;

	dek = mlx5_crypto_get_dek_by_pd(keytag, pd);
	if (spdk_unlikely(!dek)) {
		SPDK_ERRLOG("No DEK for pd %p (dev %s)\n", pd, pd->context->device->name);
		return -EINVAL;
	}
	data->dek_obj_id = dek->dek_obj_id;
	data->tweak_mode = dek->tweak_mode;

	return 0;
}

SPDK_LOG_REGISTER_COMPONENT(mlx5)
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
    spdk_mlx5_crypto_keytag_create;
    spdk_mlx5_crypto_keytag_destroy;
    spdk_mlx5_crypto_set_attr;
    spdk_mlx5_crypto_get_dek_data;
    spdk_mlx5_crypto_devs_allow;

    spdk_mlx5_mkey_pool_init;