18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2019 Google LLC
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef __LINUX_KEYSLOT_MANAGER_H
78c2ecf20Sopenharmony_ci#define __LINUX_KEYSLOT_MANAGER_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/bio.h>
108c2ecf20Sopenharmony_ci#include <linux/blk-crypto.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_cistruct blk_keyslot_manager;
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/**
158c2ecf20Sopenharmony_ci * struct blk_ksm_ll_ops - functions to manage keyslots in hardware
168c2ecf20Sopenharmony_ci * @keyslot_program:	Program the specified key into the specified slot in the
178c2ecf20Sopenharmony_ci *			inline encryption hardware.
188c2ecf20Sopenharmony_ci * @keyslot_evict:	Evict key from the specified keyslot in the hardware.
198c2ecf20Sopenharmony_ci *			The key is provided so that e.g. dm layers can evict
208c2ecf20Sopenharmony_ci *			keys from the devices that they map over.
218c2ecf20Sopenharmony_ci *			Returns 0 on success, -errno otherwise.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * This structure should be provided by storage device drivers when they set up
248c2ecf20Sopenharmony_ci * a keyslot manager - this structure holds the function ptrs that the keyslot
258c2ecf20Sopenharmony_ci * manager will use to manipulate keyslots in the hardware.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_cistruct blk_ksm_ll_ops {
288c2ecf20Sopenharmony_ci	int (*keyslot_program)(struct blk_keyslot_manager *ksm,
298c2ecf20Sopenharmony_ci			       const struct blk_crypto_key *key,
308c2ecf20Sopenharmony_ci			       unsigned int slot);
318c2ecf20Sopenharmony_ci	int (*keyslot_evict)(struct blk_keyslot_manager *ksm,
328c2ecf20Sopenharmony_ci			     const struct blk_crypto_key *key,
338c2ecf20Sopenharmony_ci			     unsigned int slot);
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct blk_keyslot_manager {
378c2ecf20Sopenharmony_ci	/*
388c2ecf20Sopenharmony_ci	 * The struct blk_ksm_ll_ops that this keyslot manager will use
398c2ecf20Sopenharmony_ci	 * to perform operations like programming and evicting keys on the
408c2ecf20Sopenharmony_ci	 * device
418c2ecf20Sopenharmony_ci	 */
428c2ecf20Sopenharmony_ci	struct blk_ksm_ll_ops ksm_ll_ops;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	/*
458c2ecf20Sopenharmony_ci	 * The maximum number of bytes supported for specifying the data unit
468c2ecf20Sopenharmony_ci	 * number.
478c2ecf20Sopenharmony_ci	 */
488c2ecf20Sopenharmony_ci	unsigned int max_dun_bytes_supported;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	/*
518c2ecf20Sopenharmony_ci	 * Array of size BLK_ENCRYPTION_MODE_MAX of bitmasks that represents
528c2ecf20Sopenharmony_ci	 * whether a crypto mode and data unit size are supported. The i'th
538c2ecf20Sopenharmony_ci	 * bit of crypto_mode_supported[crypto_mode] is set iff a data unit
548c2ecf20Sopenharmony_ci	 * size of (1 << i) is supported. We only support data unit sizes
558c2ecf20Sopenharmony_ci	 * that are powers of 2.
568c2ecf20Sopenharmony_ci	 */
578c2ecf20Sopenharmony_ci	unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX];
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	/* Device for runtime power management (NULL if none) */
608c2ecf20Sopenharmony_ci	struct device *dev;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	/* Here onwards are *private* fields for internal keyslot manager use */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	unsigned int num_slots;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* Protects programming and evicting keys from the device */
678c2ecf20Sopenharmony_ci	struct rw_semaphore lock;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	/* List of idle slots, with least recently used slot at front */
708c2ecf20Sopenharmony_ci	wait_queue_head_t idle_slots_wait_queue;
718c2ecf20Sopenharmony_ci	struct list_head idle_slots;
728c2ecf20Sopenharmony_ci	spinlock_t idle_slots_lock;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	/*
758c2ecf20Sopenharmony_ci	 * Hash table which maps struct *blk_crypto_key to keyslots, so that we
768c2ecf20Sopenharmony_ci	 * can find a key's keyslot in O(1) time rather than O(num_slots).
778c2ecf20Sopenharmony_ci	 * Protected by 'lock'.
788c2ecf20Sopenharmony_ci	 */
798c2ecf20Sopenharmony_ci	struct hlist_head *slot_hashtable;
808c2ecf20Sopenharmony_ci	unsigned int log_slot_ht_size;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	/* Per-keyslot data */
838c2ecf20Sopenharmony_ci	struct blk_ksm_keyslot *slots;
848c2ecf20Sopenharmony_ci};
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciint blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots);
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ciblk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm,
898c2ecf20Sopenharmony_ci				      const struct blk_crypto_key *key,
908c2ecf20Sopenharmony_ci				      struct blk_ksm_keyslot **slot_ptr);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciunsigned int blk_ksm_get_slot_idx(struct blk_ksm_keyslot *slot);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_civoid blk_ksm_put_slot(struct blk_ksm_keyslot *slot);
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cibool blk_ksm_crypto_cfg_supported(struct blk_keyslot_manager *ksm,
978c2ecf20Sopenharmony_ci				  const struct blk_crypto_config *cfg);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciint blk_ksm_evict_key(struct blk_keyslot_manager *ksm,
1008c2ecf20Sopenharmony_ci		      const struct blk_crypto_key *key);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_civoid blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_civoid blk_ksm_destroy(struct blk_keyslot_manager *ksm);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci#endif /* __LINUX_KEYSLOT_MANAGER_H */
107