diff mbox series

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

Message ID 447a02ca42116a422d5727e725bf90551dd0c8ba.1673873422.git.leon@kernel.org (mailing list archive)
State Not Applicable
Headers show
Series Add RDMA inline crypto support | expand

Checks

Context Check Description
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Leon Romanovsky Jan. 16, 2023, 1:05 p.m. UTC
From: Israel Rukshin <israelr@nvidia.com>

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@nvidia.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
---
 drivers/infiniband/hw/mlx5/crypto.c | 83 +++++++++++++++++++++++++++++
 drivers/infiniband/hw/mlx5/crypto.h |  8 +++
 2 files changed, 91 insertions(+)
diff mbox series

Patch

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 */