[PATCH rdma-next 09/13] RDMA/mlx5: Add DEK management API

From: Leon Romanovsky
Date: Mon Jan 16 2023 - 08:08:05 EST


From: Israel Rukshin <israelr@xxxxxxxxxx>

Add an API to manage Data Encryption Keys (DEKs). The API allows
creating and destroying a DEK. DEKs allow encryption and decryption
of transmitted data and are used in MKeys for crypto operations.

Signed-off-by: Israel Rukshin <israelr@xxxxxxxxxx>
Signed-off-by: Leon Romanovsky <leon@xxxxxxxxxx>
---
drivers/infiniband/hw/mlx5/crypto.c | 83 +++++++++++++++++++++++++++++
drivers/infiniband/hw/mlx5/crypto.h | 8 +++
2 files changed, 91 insertions(+)

diff --git a/drivers/infiniband/hw/mlx5/crypto.c b/drivers/infiniband/hw/mlx5/crypto.c
index 6fad9084877e..36e978c0fb85 100644
--- a/drivers/infiniband/hw/mlx5/crypto.c
+++ b/drivers/infiniband/hw/mlx5/crypto.c
@@ -3,6 +3,87 @@

#include "crypto.h"

+static struct ib_dek *mlx5r_create_dek(struct ib_pd *pd,
+ struct ib_dek_attr *attr)
+{
+ u32 in[MLX5_ST_SZ_DW(create_encryption_key_in)] = {};
+ u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+ struct mlx5_ib_dev *dev = to_mdev(pd->device);
+ u32 key_blob_size = attr->key_blob_size;
+ void *ptr, *key_addr;
+ struct ib_dek *dek;
+ u8 key_size;
+ int err;
+
+ if (attr->key_type != IB_CRYPTO_KEY_TYPE_AES_XTS)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ switch (key_blob_size) {
+ case MLX5_IB_CRYPTO_AES_128_XTS_KEY_SIZE:
+ key_size = MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_KEY_SIZE_128;
+ break;
+ case MLX5_IB_CRYPTO_AES_256_XTS_KEY_SIZE:
+ key_size = MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_KEY_SIZE_256;
+ break;
+ default:
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
+ dek = kzalloc(sizeof(*dek), GFP_KERNEL);
+ if (!dek)
+ return ERR_PTR(-ENOMEM);
+
+ ptr = MLX5_ADDR_OF(create_encryption_key_in, in,
+ general_obj_in_cmd_hdr);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
+ MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
+ MLX5_GENERAL_OBJECT_TYPES_ENCRYPTION_KEY);
+ ptr = MLX5_ADDR_OF(create_encryption_key_in, in, encryption_key_object);
+ MLX5_SET(encryption_key_obj, ptr, key_size, key_size);
+ MLX5_SET(encryption_key_obj, ptr, key_type,
+ MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_TYPE_AES_XTS);
+ MLX5_SET(encryption_key_obj, ptr, pd, to_mpd(pd)->pdn);
+ key_addr = MLX5_ADDR_OF(encryption_key_obj, ptr, key);
+ memcpy(key_addr, attr->key_blob, key_blob_size);
+
+ err = mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
+ /* avoid leaking key on the stack */
+ memzero_explicit(in, sizeof(in));
+ if (err)
+ goto err_free;
+
+ dek->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
+ dek->pd = pd;
+
+ return dek;
+
+err_free:
+ kfree(dek);
+ return ERR_PTR(err);
+}
+
+static void mlx5r_destroy_dek(struct ib_dek *dek)
+{
+ struct mlx5_ib_dev *dev = to_mdev(dek->pd->device);
+ u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
+ u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
+
+ MLX5_SET(general_obj_in_cmd_hdr, in, opcode,
+ MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_type,
+ MLX5_GENERAL_OBJECT_TYPES_ENCRYPTION_KEY);
+ MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, dek->id);
+
+ mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
+ kfree(dek);
+}
+
+static const struct ib_device_ops mlx5r_dev_crypto_ops = {
+ .create_dek = mlx5r_create_dek,
+ .destroy_dek = mlx5r_destroy_dek,
+};
+
void mlx5r_crypto_caps_init(struct mlx5_ib_dev *dev)
{
struct ib_crypto_caps *caps = &dev->crypto_caps;
@@ -28,4 +109,6 @@ void mlx5r_crypto_caps_init(struct mlx5_ib_dev *dev)

caps->crypto_engines |= IB_CRYPTO_ENGINES_CAP_AES_XTS;
caps->max_num_deks = 1 << MLX5_CAP_CRYPTO(mdev, log_max_num_deks);
+
+ ib_set_device_ops(&dev->ib_dev, &mlx5r_dev_crypto_ops);
}
diff --git a/drivers/infiniband/hw/mlx5/crypto.h b/drivers/infiniband/hw/mlx5/crypto.h
index 8686ac6fb0b0..b132b780030f 100644
--- a/drivers/infiniband/hw/mlx5/crypto.h
+++ b/drivers/infiniband/hw/mlx5/crypto.h
@@ -6,6 +6,14 @@

#include "mlx5_ib.h"

+/*
+ * The standard AES-XTS key blob composed of two keys.
+ * AES-128-XTS key blob composed of two 128-bit keys, which is 32 bytes and
+ * AES-256-XTS key blob composed of two 256-bit keys, which is 64 bytes.
+ */
+#define MLX5_IB_CRYPTO_AES_128_XTS_KEY_SIZE 32
+#define MLX5_IB_CRYPTO_AES_256_XTS_KEY_SIZE 64
+
void mlx5r_crypto_caps_init(struct mlx5_ib_dev *dev);

#endif /* _MLX5_IB_CRYPTO_H */
--
2.39.0