Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <satyat@google.com>
Reviewed-by: Eric Biggers <ebiggers@google.com>
Acked-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Satya Tangirala and committed by
Mike Snitzer
7bdcc48f cca2c6ae

+41
+39
block/keyslot-manager.c
··· 62 62 pm_runtime_put_sync(ksm->dev); 63 63 } 64 64 65 + static inline bool blk_ksm_is_passthrough(struct blk_keyslot_manager *ksm) 66 + { 67 + return ksm->num_slots == 0; 68 + } 69 + 65 70 /** 66 71 * blk_ksm_init() - Initialize a keyslot manager 67 72 * @ksm: The keyslot_manager to initialize. ··· 210 205 int err; 211 206 212 207 *slot_ptr = NULL; 208 + 209 + if (blk_ksm_is_passthrough(ksm)) 210 + return BLK_STS_OK; 211 + 213 212 down_read(&ksm->lock); 214 213 slot = blk_ksm_find_and_grab_keyslot(ksm, key); 215 214 up_read(&ksm->lock); ··· 334 325 struct blk_ksm_keyslot *slot; 335 326 int err = 0; 336 327 328 + if (blk_ksm_is_passthrough(ksm)) { 329 + if (ksm->ksm_ll_ops.keyslot_evict) { 330 + blk_ksm_hw_enter(ksm); 331 + err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, -1); 332 + blk_ksm_hw_exit(ksm); 333 + return err; 334 + } 335 + return 0; 336 + } 337 + 337 338 blk_ksm_hw_enter(ksm); 338 339 slot = blk_ksm_find_keyslot(ksm, key); 339 340 if (!slot) ··· 378 359 void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm) 379 360 { 380 361 unsigned int slot; 362 + 363 + if (blk_ksm_is_passthrough(ksm)) 364 + return; 381 365 382 366 /* This is for device initialization, so don't resume the device */ 383 367 down_write(&ksm->lock); ··· 423 401 { 424 402 q->ksm = NULL; 425 403 } 404 + 405 + /** 406 + * blk_ksm_init_passthrough() - Init a passthrough keyslot manager 407 + * @ksm: The keyslot manager to init 408 + * 409 + * Initialize a passthrough keyslot manager. 410 + * Called by e.g. storage drivers to set up a keyslot manager in their 411 + * request_queue, when the storage driver wants to manage its keys by itself. 412 + * This is useful for inline encryption hardware that doesn't have the concept 413 + * of keyslots, and for layered devices. 414 + */ 415 + void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm) 416 + { 417 + memset(ksm, 0, sizeof(*ksm)); 418 + init_rwsem(&ksm->lock); 419 + } 420 + EXPORT_SYMBOL_GPL(blk_ksm_init_passthrough);
+2
include/linux/keyslot-manager.h
··· 103 103 104 104 void blk_ksm_destroy(struct blk_keyslot_manager *ksm); 105 105 106 + void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm); 107 + 106 108 #endif /* __LINUX_KEYSLOT_MANAGER_H */