[RFC,2/5] crypto/mlx5: add AES-GCM encryption key

Message ID 20230418092325.2578712-3-suanmingm@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series crypto/mlx5: support AES-GCM |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Suanming Mou April 18, 2023, 9:23 a.m. UTC
  The crypto device requires the DEK(data encryption key) object for
data encryption/decryption operation.

This commit adds the AES-GCM DEK object management support.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c  |   6 +-
 drivers/common/mlx5/mlx5_devx_cmds.h  |   1 +
 drivers/common/mlx5/mlx5_prm.h        |   6 +-
 drivers/crypto/mlx5/mlx5_crypto.c     |   2 +-
 drivers/crypto/mlx5/mlx5_crypto.h     |   3 +-
 drivers/crypto/mlx5/mlx5_crypto_dek.c | 157 ++++++++++++++++++++------
 drivers/crypto/mlx5/mlx5_crypto_gcm.c |   2 +
 7 files changed, 137 insertions(+), 40 deletions(-)
  

Patch

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 592a7cffdb..8b51a75cc8 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -3166,10 +3166,14 @@  mlx5_devx_cmd_create_dek_obj(void *ctx, struct mlx5_devx_dek_attr *attr)
 	ptr = MLX5_ADDR_OF(create_dek_in, in, dek);
 	MLX5_SET(dek, ptr, key_size, attr->key_size);
 	MLX5_SET(dek, ptr, has_keytag, attr->has_keytag);
+	MLX5_SET(dek, ptr, sw_wrapped, attr->sw_wrapped);
 	MLX5_SET(dek, ptr, key_purpose, attr->key_purpose);
 	MLX5_SET(dek, ptr, pd, attr->pd);
 	MLX5_SET64(dek, ptr, opaque, attr->opaque);
-	key_addr = MLX5_ADDR_OF(dek, ptr, key);
+	if (attr->sw_wrapped)
+		key_addr = MLX5_ADDR_OF(dek, ptr, sw_wrapped_dek);
+	else
+		key_addr = MLX5_ADDR_OF(dek, ptr, key);
 	memcpy(key_addr, (void *)(attr->key), MLX5_CRYPTO_KEY_MAX_SIZE);
 	dek_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
 						  out, sizeof(out));
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index d640482346..79502cda08 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -664,6 +664,7 @@  struct mlx5_devx_dek_attr {
 	uint32_t key_size:4;
 	uint32_t has_keytag:1;
 	uint32_t key_purpose:4;
+	uint32_t sw_wrapped:1;
 	uint32_t pd:24;
 	uint64_t opaque;
 	uint8_t key[MLX5_CRYPTO_KEY_MAX_SIZE];
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index a3b85f514e..9728be24dd 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -3736,7 +3736,8 @@  enum {
 struct mlx5_ifc_dek_bits {
 	u8 modify_field_select[0x40];
 	u8 state[0x8];
-	u8 reserved_at_48[0xc];
+	u8 sw_wrapped[0x1];
+	u8 reserved_at_49[0xb];
 	u8 key_size[0x4];
 	u8 has_keytag[0x1];
 	u8 reserved_at_59[0x3];
@@ -3747,7 +3748,8 @@  struct mlx5_ifc_dek_bits {
 	u8 opaque[0x40];
 	u8 reserved_at_1c0[0x40];
 	u8 key[0x400];
-	u8 reserved_at_600[0x200];
+	u8 sw_wrapped_dek[0x400];
+	u8 reserved_at_a00[0x300];
 };
 
 struct mlx5_ifc_create_dek_in_bits {
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index 6963d8a9c9..66c9f94346 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -196,7 +196,7 @@  mlx5_crypto_sym_session_configure(struct rte_cryptodev *dev,
 		return -ENOTSUP;
 	}
 	cipher = &xform->cipher;
-	sess_private_data->dek = mlx5_crypto_dek_prepare(priv, cipher);
+	sess_private_data->dek = mlx5_crypto_dek_prepare(priv, xform);
 	if (sess_private_data->dek == NULL) {
 		DRV_LOG(ERR, "Failed to prepare dek.");
 		return -ENOMEM;
diff --git a/drivers/crypto/mlx5/mlx5_crypto.h b/drivers/crypto/mlx5/mlx5_crypto.h
index 80c2cab0dd..11352f9409 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.h
+++ b/drivers/crypto/mlx5/mlx5_crypto.h
@@ -40,6 +40,7 @@  struct mlx5_crypto_priv {
 	uint16_t umr_wqe_stride;
 	uint16_t max_rdmar_ds;
 	uint32_t is_wrapped_mode:1;
+	uint32_t is_gcm_dek_wrap:1;
 };
 
 struct mlx5_crypto_qp {
@@ -78,7 +79,7 @@  mlx5_crypto_dek_destroy(struct mlx5_crypto_priv *priv,
 
 struct mlx5_crypto_dek *
 mlx5_crypto_dek_prepare(struct mlx5_crypto_priv *priv,
-			struct rte_crypto_cipher_xform *cipher);
+			struct rte_crypto_sym_xform *xform);
 
 int
 mlx5_crypto_dek_setup(struct mlx5_crypto_priv *priv);
diff --git a/drivers/crypto/mlx5/mlx5_crypto_dek.c b/drivers/crypto/mlx5/mlx5_crypto_dek.c
index 7339ef2bd9..ba6dab52f7 100644
--- a/drivers/crypto/mlx5/mlx5_crypto_dek.c
+++ b/drivers/crypto/mlx5/mlx5_crypto_dek.c
@@ -14,10 +14,29 @@ 
 #include "mlx5_crypto.h"
 
 struct mlx5_crypto_dek_ctx {
-	struct rte_crypto_cipher_xform *cipher;
+	struct rte_crypto_sym_xform *xform;
 	struct mlx5_crypto_priv *priv;
 };
 
+static int
+mlx5_crypto_dek_get_key(struct rte_crypto_sym_xform *xform,
+			const uint8_t **key,
+			uint16_t *key_len)
+{
+	if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
+		*key = xform->cipher.key.data;
+		*key_len = xform->cipher.key.length;
+	} else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
+		*key = xform->aead.key.data;
+		*key_len = xform->aead.key.length;
+	} else {
+		DRV_LOG(ERR, "Xform dek type not supported.");
+		rte_errno = -EINVAL;
+		return -1;
+	}
+	return 0;
+}
+
 int
 mlx5_crypto_dek_destroy(struct mlx5_crypto_priv *priv,
 			struct mlx5_crypto_dek *dek)
@@ -27,19 +46,22 @@  mlx5_crypto_dek_destroy(struct mlx5_crypto_priv *priv,
 
 struct mlx5_crypto_dek *
 mlx5_crypto_dek_prepare(struct mlx5_crypto_priv *priv,
-			struct rte_crypto_cipher_xform *cipher)
+			struct rte_crypto_sym_xform *xform)
 {
+	const uint8_t *key;
+	uint16_t key_len;
 	struct mlx5_hlist *dek_hlist = priv->dek_hlist;
 	struct mlx5_crypto_dek_ctx dek_ctx = {
-		.cipher = cipher,
+		.xform = xform,
 		.priv = priv,
 	};
-	struct rte_crypto_cipher_xform *cipher_ctx = cipher;
-	uint64_t key64 = __rte_raw_cksum(cipher_ctx->key.data,
-					 cipher_ctx->key.length, 0);
-	struct mlx5_list_entry *entry = mlx5_hlist_register(dek_hlist,
-							     key64, &dek_ctx);
+	uint64_t key64;
+	struct mlx5_list_entry *entry;
 
+	if (mlx5_crypto_dek_get_key(xform, &key, &key_len))
+		return NULL;
+	key64 = __rte_raw_cksum(key, key_len, 0);
+	entry = mlx5_hlist_register(dek_hlist, key64, &dek_ctx);
 	return entry == NULL ? NULL :
 			     container_of(entry, struct mlx5_crypto_dek, entry);
 }
@@ -76,76 +98,141 @@  mlx5_crypto_dek_match_cb(void *tool_ctx __rte_unused,
 			 struct mlx5_list_entry *entry, void *cb_ctx)
 {
 	struct mlx5_crypto_dek_ctx *ctx = cb_ctx;
-	struct rte_crypto_cipher_xform *cipher_ctx = ctx->cipher;
+	struct rte_crypto_sym_xform *xform = ctx->xform;
 	struct mlx5_crypto_dek *dek =
 			container_of(entry, typeof(*dek), entry);
 	uint32_t key_len = dek->size;
+	uint16_t xkey_len;
+	const uint8_t *key;
 
-	if (key_len != cipher_ctx->key.length)
+	if (mlx5_crypto_dek_get_key(xform, &key, &xkey_len))
+		return -1;
+	if (key_len != xkey_len)
 		return -1;
-	return memcmp(cipher_ctx->key.data, dek->data, cipher_ctx->key.length);
+	return memcmp(key, dek->data, xkey_len);
 }
 
-static struct mlx5_list_entry *
-mlx5_crypto_dek_create_cb(void *tool_ctx __rte_unused, void *cb_ctx)
+static int
+mlx5_crypto_dek_create_aes_xts(struct mlx5_crypto_dek *dek,
+		struct mlx5_devx_dek_attr *dek_attr,
+		void *cb_ctx)
 {
 	struct mlx5_crypto_dek_ctx *ctx = cb_ctx;
-	struct rte_crypto_cipher_xform *cipher_ctx = ctx->cipher;
-	struct mlx5_crypto_dek *dek = rte_zmalloc(__func__, sizeof(*dek),
-						  RTE_CACHE_LINE_SIZE);
-	struct mlx5_devx_dek_attr dek_attr = {
-		.pd = ctx->priv->cdev->pdn,
-		.key_purpose = MLX5_CRYPTO_KEY_PURPOSE_AES_XTS,
-		.has_keytag = 1,
-	};
+	struct rte_crypto_cipher_xform *cipher_ctx = &ctx->xform->cipher;
 	bool is_wrapped = ctx->priv->is_wrapped_mode;
 
-	if (dek == NULL) {
-		DRV_LOG(ERR, "Failed to allocate dek memory.");
-		return NULL;
+	if (cipher_ctx->algo != RTE_CRYPTO_CIPHER_AES_XTS) {
+		DRV_LOG(ERR, "Only AES-XTS algo supported.");
+		return -EINVAL;
 	}
+	dek_attr->key_purpose = MLX5_CRYPTO_KEY_PURPOSE_AES_XTS;
+	dek_attr->has_keytag = 1;
 	if (is_wrapped) {
 		switch (cipher_ctx->key.length) {
 		case 48:
 			dek->size = 48;
-			dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_128b;
+			dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_128b;
 			break;
 		case 80:
 			dek->size = 80;
-			dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_256b;
+			dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_256b;
 			break;
 		default:
 			DRV_LOG(ERR, "Wrapped key size not supported.");
-			return NULL;
+			return -EINVAL;
 		}
 	} else {
 		switch (cipher_ctx->key.length) {
 		case 32:
 			dek->size = 40;
-			dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_128b;
+			dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_128b;
 			break;
 		case 64:
 			dek->size = 72;
-			dek_attr.key_size = MLX5_CRYPTO_KEY_SIZE_256b;
+			dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_256b;
 			break;
 		default:
 			DRV_LOG(ERR, "Key size not supported.");
-			return NULL;
+			return -EINVAL;
 		}
-		memcpy(&dek_attr.key[cipher_ctx->key.length],
+		memcpy(&dek_attr->key[cipher_ctx->key.length],
 						&ctx->priv->keytag, 8);
 	}
-	memcpy(&dek_attr.key, cipher_ctx->key.data, cipher_ctx->key.length);
+	memcpy(&dek_attr->key, cipher_ctx->key.data, cipher_ctx->key.length);
+	memcpy(&dek->data, cipher_ctx->key.data, cipher_ctx->key.length);
+	return 0;
+}
+
+static int
+mlx5_crypto_dek_create_aes_gcm(struct mlx5_crypto_dek *dek,
+		struct mlx5_devx_dek_attr *dek_attr,
+		void *cb_ctx)
+{
+	struct mlx5_crypto_dek_ctx *ctx = cb_ctx;
+	struct rte_crypto_aead_xform *aead_ctx = &ctx->xform->aead;
+
+	if (aead_ctx->algo != RTE_CRYPTO_AEAD_AES_GCM) {
+		DRV_LOG(ERR, "Only AES-GCM algo supported.");
+		return -EINVAL;
+	}
+	dek_attr->key_purpose = MLX5_CRYPTO_KEY_PURPOSE_GCM;
+	switch (aead_ctx->key.length) {
+	case 16:
+		dek->size = 16;
+		dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_128b;
+		break;
+	case 32:
+		dek->size = 32;
+		dek_attr->key_size = MLX5_CRYPTO_KEY_SIZE_256b;
+		break;
+	default:
+		DRV_LOG(ERR, "Wrapped key size not supported.");
+		return -EINVAL;
+	}
+#ifdef MLX5_DEK_WRAP
+	if (ctx->priv->is_gcm_dek_wrap)
+		dek_attr->sw_wrapped = 1;
+#endif
+	memcpy(&dek_attr->key, aead_ctx->key.data, aead_ctx->key.length);
+	memcpy(&dek->data, aead_ctx->key.data, aead_ctx->key.length);
+	return 0;
+}
+
+static struct mlx5_list_entry *
+mlx5_crypto_dek_create_cb(void *tool_ctx __rte_unused, void *cb_ctx)
+{
+	struct mlx5_crypto_dek_ctx *ctx = cb_ctx;
+	struct rte_crypto_sym_xform *xform = ctx->xform;
+	struct mlx5_crypto_dek *dek = rte_zmalloc(__func__, sizeof(*dek),
+						  RTE_CACHE_LINE_SIZE);
+	struct mlx5_devx_dek_attr dek_attr = {
+		.pd = ctx->priv->cdev->pdn,
+	};
+	int ret = -1;
+
+	if (dek == NULL) {
+		DRV_LOG(ERR, "Failed to allocate dek memory.");
+		return NULL;
+	}
+	if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
+		ret = mlx5_crypto_dek_create_aes_xts(dek, &dek_attr, cb_ctx);
+	else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
+		ret = mlx5_crypto_dek_create_aes_gcm(dek, &dek_attr, cb_ctx);
+	if (ret)
+		goto fail;
 	dek->obj = mlx5_devx_cmd_create_dek_obj(ctx->priv->cdev->ctx,
 						&dek_attr);
 	if (dek->obj == NULL) {
-		rte_free(dek);
-		return NULL;
+		DRV_LOG(ERR, "Failed to create dek obj.");
+		goto fail;
 	}
-	memcpy(&dek->data, cipher_ctx->key.data, cipher_ctx->key.length);
 	return &dek->entry;
+fail:
+	rte_free(dek);
+	return NULL;
 }
 
+
 static void
 mlx5_crypto_dek_remove_cb(void *tool_ctx __rte_unused,
 			  struct mlx5_list_entry *entry)
diff --git a/drivers/crypto/mlx5/mlx5_crypto_gcm.c b/drivers/crypto/mlx5/mlx5_crypto_gcm.c
index d60ac379cf..c7fd86d7b9 100644
--- a/drivers/crypto/mlx5/mlx5_crypto_gcm.c
+++ b/drivers/crypto/mlx5/mlx5_crypto_gcm.c
@@ -95,6 +95,8 @@  mlx5_crypto_gcm_init(struct mlx5_crypto_priv *priv)
 		return -1;
 	}
 	priv->caps = mlx5_crypto_gcm_caps;
+	priv->is_gcm_dek_wrap = !!(cdev->config.hca_attr.sw_wrapped_dek &
+				(1 << MLX5_CRYPTO_KEY_PURPOSE_GCM));
 	return 0;
 }