Skip to content

Commit 7bdcc48

Browse files
Satya Tangiralasnitm
authored andcommitted
block/keyslot-manager: Introduce passthrough keyslot manager
The device mapper may map over devices that have inline encryption capabilities, and to make use of those capabilities, the DM device must itself advertise those inline encryption capabilities. One way to do this would be to have the DM device set up a keyslot manager with a "sufficiently large" number of keyslots, but that would use a lot of memory. Also, the DM device itself has no "keyslots", and it doesn't make much sense to talk about "programming a key into a DM device's keyslot manager", so all that extra memory used to represent those keyslots is just wasted. All a DM device really needs to be able to do is advertise the crypto capabilities of the underlying devices in a coherent manner and expose a way to evict keys from the underlying devices. There are also devices with inline encryption hardware that do not have a limited number of keyslots. One can send a raw encryption key along with a bio to these devices (as opposed to typical inline encryption hardware that require users to first program a raw encryption key into a keyslot, and send the index of that keyslot along with the bio). These devices also only need the same things from the keyslot manager that DM devices need - a way to advertise crypto capabilities and potentially a way to expose a function to evict keys from hardware. So we introduce a "passthrough" keyslot manager that provides a way to represent a keyslot manager that doesn't have just a limited number of keyslots, and for which do not require keys to be programmed into keyslots. DM devices can set up a passthrough keyslot manager in their request queues, and advertise appropriate crypto capabilities based on those of the underlying devices. Blk-crypto does not attempt to program keys into any keyslots in the passthrough keyslot manager. Instead, if/when the bio is resubmitted to the underlying device, blk-crypto will try to program the key into the underlying device's keyslot manager. Signed-off-by: Satya Tangirala <[email protected]> Reviewed-by: Eric Biggers <[email protected]> Acked-by: Jens Axboe <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent cca2c6a commit 7bdcc48

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

block/keyslot-manager.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ static inline void blk_ksm_hw_exit(struct blk_keyslot_manager *ksm)
6262
pm_runtime_put_sync(ksm->dev);
6363
}
6464

65+
static inline bool blk_ksm_is_passthrough(struct blk_keyslot_manager *ksm)
66+
{
67+
return ksm->num_slots == 0;
68+
}
69+
6570
/**
6671
* blk_ksm_init() - Initialize a keyslot manager
6772
* @ksm: The keyslot_manager to initialize.
@@ -205,6 +210,10 @@ blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm,
205210
int err;
206211

207212
*slot_ptr = NULL;
213+
214+
if (blk_ksm_is_passthrough(ksm))
215+
return BLK_STS_OK;
216+
208217
down_read(&ksm->lock);
209218
slot = blk_ksm_find_and_grab_keyslot(ksm, key);
210219
up_read(&ksm->lock);
@@ -325,6 +334,16 @@ int blk_ksm_evict_key(struct blk_keyslot_manager *ksm,
325334
struct blk_ksm_keyslot *slot;
326335
int err = 0;
327336

337+
if (blk_ksm_is_passthrough(ksm)) {
338+
if (ksm->ksm_ll_ops.keyslot_evict) {
339+
blk_ksm_hw_enter(ksm);
340+
err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, -1);
341+
blk_ksm_hw_exit(ksm);
342+
return err;
343+
}
344+
return 0;
345+
}
346+
328347
blk_ksm_hw_enter(ksm);
329348
slot = blk_ksm_find_keyslot(ksm, key);
330349
if (!slot)
@@ -360,6 +379,9 @@ void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm)
360379
{
361380
unsigned int slot;
362381

382+
if (blk_ksm_is_passthrough(ksm))
383+
return;
384+
363385
/* This is for device initialization, so don't resume the device */
364386
down_write(&ksm->lock);
365387
for (slot = 0; slot < ksm->num_slots; slot++) {
@@ -401,3 +423,20 @@ void blk_ksm_unregister(struct request_queue *q)
401423
{
402424
q->ksm = NULL;
403425
}
426+
427+
/**
428+
* blk_ksm_init_passthrough() - Init a passthrough keyslot manager
429+
* @ksm: The keyslot manager to init
430+
*
431+
* Initialize a passthrough keyslot manager.
432+
* Called by e.g. storage drivers to set up a keyslot manager in their
433+
* request_queue, when the storage driver wants to manage its keys by itself.
434+
* This is useful for inline encryption hardware that doesn't have the concept
435+
* of keyslots, and for layered devices.
436+
*/
437+
void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm)
438+
{
439+
memset(ksm, 0, sizeof(*ksm));
440+
init_rwsem(&ksm->lock);
441+
}
442+
EXPORT_SYMBOL_GPL(blk_ksm_init_passthrough);

include/linux/keyslot-manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,6 @@ void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm);
103103

104104
void blk_ksm_destroy(struct blk_keyslot_manager *ksm);
105105

106+
void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm);
107+
106108
#endif /* __LINUX_KEYSLOT_MANAGER_H */

0 commit comments

Comments
 (0)