From f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 31 Jan 2024 01:04:47 +0000
Subject: [PATCH] add driver 5G

---
 kernel/include/linux/keyslot-manager.h |  132 +++++++++++++++++++++++++++++--------------
 1 files changed, 88 insertions(+), 44 deletions(-)

diff --git a/kernel/include/linux/keyslot-manager.h b/kernel/include/linux/keyslot-manager.h
index f5e0eed..2eb44e2 100644
--- a/kernel/include/linux/keyslot-manager.h
+++ b/kernel/include/linux/keyslot-manager.h
@@ -7,6 +7,7 @@
 #define __LINUX_KEYSLOT_MANAGER_H
 
 #include <linux/bio.h>
+#include <linux/blk-crypto.h>
 
 /* Inline crypto feature bits.  Must set at least one. */
 enum {
@@ -17,12 +18,10 @@
 	BLK_CRYPTO_FEATURE_WRAPPED_KEYS = BIT(1),
 };
 
-#ifdef CONFIG_BLK_INLINE_ENCRYPTION
-
-struct keyslot_manager;
+struct blk_keyslot_manager;
 
 /**
- * struct keyslot_mgmt_ll_ops - functions to manage keyslots in hardware
+ * struct blk_ksm_ll_ops - functions to manage keyslots in hardware
  * @keyslot_program:	Program the specified key into the specified slot in the
  *			inline encryption hardware.
  * @keyslot_evict:	Evict key from the specified keyslot in the hardware.
@@ -37,67 +36,112 @@
  * a keyslot manager - this structure holds the function ptrs that the keyslot
  * manager will use to manipulate keyslots in the hardware.
  */
-struct keyslot_mgmt_ll_ops {
-	int (*keyslot_program)(struct keyslot_manager *ksm,
+struct blk_ksm_ll_ops {
+	int (*keyslot_program)(struct blk_keyslot_manager *ksm,
 			       const struct blk_crypto_key *key,
 			       unsigned int slot);
-	int (*keyslot_evict)(struct keyslot_manager *ksm,
+	int (*keyslot_evict)(struct blk_keyslot_manager *ksm,
 			     const struct blk_crypto_key *key,
 			     unsigned int slot);
-	int (*derive_raw_secret)(struct keyslot_manager *ksm,
+	int (*derive_raw_secret)(struct blk_keyslot_manager *ksm,
 				 const u8 *wrapped_key,
 				 unsigned int wrapped_key_size,
 				 u8 *secret, unsigned int secret_size);
 };
 
-struct keyslot_manager *keyslot_manager_create(
-	struct device *dev,
-	unsigned int num_slots,
-	const struct keyslot_mgmt_ll_ops *ksm_ops,
-	unsigned int features,
-	const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
-	void *ll_priv_data);
+struct blk_keyslot_manager {
+	/*
+	 * The struct blk_ksm_ll_ops that this keyslot manager will use
+	 * to perform operations like programming and evicting keys on the
+	 * device
+	 */
+	struct blk_ksm_ll_ops ksm_ll_ops;
 
-void keyslot_manager_set_max_dun_bytes(struct keyslot_manager *ksm,
-				       unsigned int max_dun_bytes);
+	/*
+	 * The maximum number of bytes supported for specifying the data unit
+	 * number.
+	 */
+	unsigned int max_dun_bytes_supported;
 
-int keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm,
-				     const struct blk_crypto_key *key);
+	/*
+	 * The supported features as a bitmask of BLK_CRYPTO_FEATURE_* flags.
+	 * Most drivers should set BLK_CRYPTO_FEATURE_STANDARD_KEYS here.
+	 */
+	unsigned int features;
 
-void keyslot_manager_get_slot(struct keyslot_manager *ksm, unsigned int slot);
+	/*
+	 * Array of size BLK_ENCRYPTION_MODE_MAX of bitmasks that represents
+	 * whether a crypto mode and data unit size are supported. The i'th
+	 * bit of crypto_mode_supported[crypto_mode] is set iff a data unit
+	 * size of (1 << i) is supported. We only support data unit sizes
+	 * that are powers of 2.
+	 */
+	unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX];
 
-void keyslot_manager_put_slot(struct keyslot_manager *ksm, unsigned int slot);
+	/* Device for runtime power management (NULL if none) */
+	struct device *dev;
 
-bool keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm,
-					   enum blk_crypto_mode_num crypto_mode,
-					   unsigned int dun_bytes,
-					   unsigned int data_unit_size,
-					   bool is_hw_wrapped_key);
+	/* Here onwards are *private* fields for internal keyslot manager use */
 
-int keyslot_manager_evict_key(struct keyslot_manager *ksm,
-			      const struct blk_crypto_key *key);
+	unsigned int num_slots;
 
-void keyslot_manager_reprogram_all_keys(struct keyslot_manager *ksm);
+	/* Protects programming and evicting keys from the device */
+	struct rw_semaphore lock;
 
-void *keyslot_manager_private(struct keyslot_manager *ksm);
+	/* List of idle slots, with least recently used slot at front */
+	wait_queue_head_t idle_slots_wait_queue;
+	struct list_head idle_slots;
+	spinlock_t idle_slots_lock;
 
-void keyslot_manager_destroy(struct keyslot_manager *ksm);
+	/*
+	 * Hash table which maps struct *blk_crypto_key to keyslots, so that we
+	 * can find a key's keyslot in O(1) time rather than O(num_slots).
+	 * Protected by 'lock'.
+	 */
+	struct hlist_head *slot_hashtable;
+	unsigned int log_slot_ht_size;
 
-struct keyslot_manager *keyslot_manager_create_passthrough(
-	struct device *dev,
-	const struct keyslot_mgmt_ll_ops *ksm_ops,
-	unsigned int features,
-	const unsigned int crypto_mode_supported[BLK_ENCRYPTION_MODE_MAX],
-	void *ll_priv_data);
+	/* Per-keyslot data */
+	struct blk_ksm_keyslot *slots;
+};
 
-void keyslot_manager_intersect_modes(struct keyslot_manager *parent,
-				     const struct keyslot_manager *child);
+int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots);
 
-int keyslot_manager_derive_raw_secret(struct keyslot_manager *ksm,
-				      const u8 *wrapped_key,
-				      unsigned int wrapped_key_size,
-				      u8 *secret, unsigned int secret_size);
+int devm_blk_ksm_init(struct device *dev, struct blk_keyslot_manager *ksm,
+		      unsigned int num_slots);
 
-#endif /* CONFIG_BLK_INLINE_ENCRYPTION */
+blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm,
+				      const struct blk_crypto_key *key,
+				      struct blk_ksm_keyslot **slot_ptr);
+
+unsigned int blk_ksm_get_slot_idx(struct blk_ksm_keyslot *slot);
+
+void blk_ksm_put_slot(struct blk_ksm_keyslot *slot);
+
+bool blk_ksm_crypto_cfg_supported(struct blk_keyslot_manager *ksm,
+				  const struct blk_crypto_config *cfg);
+
+int blk_ksm_evict_key(struct blk_keyslot_manager *ksm,
+		      const struct blk_crypto_key *key);
+
+void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm);
+
+void blk_ksm_destroy(struct blk_keyslot_manager *ksm);
+
+int blk_ksm_derive_raw_secret(struct blk_keyslot_manager *ksm,
+			      const u8 *wrapped_key,
+			      unsigned int wrapped_key_size,
+			      u8 *secret, unsigned int secret_size);
+
+void blk_ksm_intersect_modes(struct blk_keyslot_manager *parent,
+			     const struct blk_keyslot_manager *child);
+
+void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm);
+
+bool blk_ksm_is_superset(struct blk_keyslot_manager *ksm_superset,
+			 struct blk_keyslot_manager *ksm_subset);
+
+void blk_ksm_update_capabilities(struct blk_keyslot_manager *target_ksm,
+				 struct blk_keyslot_manager *reference_ksm);
 
 #endif /* __LINUX_KEYSLOT_MANAGER_H */

--
Gitblit v1.6.2