| /* SPDX-License-Identifier: GPL-2.0 */ | |
| /* | |
| * Copyright 2019 Google LLC | |
| */ | |
| #ifndef __LINUX_KEYSLOT_MANAGER_H | |
| #define __LINUX_KEYSLOT_MANAGER_H | |
| #include <linux/bio.h> | |
| #include <linux/blk-crypto.h> | |
| struct blk_keyslot_manager; | |
| /** | |
| * 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. | |
| * The key is provided so that e.g. dm layers can evict | |
| * keys from the devices that they map over. | |
| * Returns 0 on success, -errno otherwise. | |
| * | |
| * This structure should be provided by storage device drivers when they set up | |
| * a keyslot manager - this structure holds the function ptrs that the keyslot | |
| * manager will use to manipulate keyslots in the hardware. | |
| */ | |
| 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 blk_keyslot_manager *ksm, | |
| const struct blk_crypto_key *key, | |
| unsigned int slot); | |
| }; | |
| 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; | |
| /* | |
| * The maximum number of bytes supported for specifying the data unit | |
| * number. | |
| */ | |
| unsigned int max_dun_bytes_supported; | |
| /* | |
| * 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]; | |
| /* Device for runtime power management (NULL if none) */ | |
| struct device *dev; | |
| /* Here onwards are *private* fields for internal keyslot manager use */ | |
| unsigned int num_slots; | |
| /* Protects programming and evicting keys from the device */ | |
| struct rw_semaphore lock; | |
| /* 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; | |
| /* | |
| * 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; | |
| /* Per-keyslot data */ | |
| struct blk_ksm_keyslot *slots; | |
| }; | |
| int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots); | |
| 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); | |
| #endif /* __LINUX_KEYSLOT_MANAGER_H */ |