/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2019 Google LLC */ #ifndef __LINUX_KEYSLOT_MANAGER_H #define __LINUX_KEYSLOT_MANAGER_H #include #include 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 */