@@ -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));
@@ -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];
@@ -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 {
@@ -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;
@@ -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);
@@ -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)
@@ -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;
}