Message ID | 20201015214632.41951-2-satyat@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | add support for inline encryption to device mapper | expand |
And this just validates my argument that calling the inline crypto work directly from the block layer instead of just down below in blk-mq was wrong. We should not require any support from stacking drivers at the keyslot manager level.
On Fri, Oct 16, 2020 at 08:20:44AM +0100, Christoph Hellwig wrote: > And this just validates my argument that calling the inline crypto work > directly from the block layer instead of just down below in blk-mq was > wrong. We should not require any support from stacking drivers at the > keyslot manager level. I'm not sure what you're referring to here; could you clarify? It's true that device-mapper devices don't need the actual keyslot management. But they do need the ability to expose crypto capabilities as well as a key eviction function. And those are currently handled by "struct blk_keyslot_manager". Hence the need for a "passthrough keyslot manager" that does those other things but not the actual keyslot management. FWIW, I suggested splitting these up, but you disagreed and said you wanted the crypto capabilities to remain part of the blk_keyslot_manager (https://lkml.kernel.org/linux-block/20200327170047.GA24682@infradead.org/). If you've now changed your mind, please be clear about it. - Eric
On Tue, Oct 20, 2020 at 09:44:23PM -0700, Eric Biggers wrote: > On Fri, Oct 16, 2020 at 08:20:44AM +0100, Christoph Hellwig wrote: > > And this just validates my argument that calling the inline crypto work > > directly from the block layer instead of just down below in blk-mq was > > wrong. We should not require any support from stacking drivers at the > > keyslot manager level. > > I'm not sure what you're referring to here; could you clarify? > > It's true that device-mapper devices don't need the actual keyslot management. > But they do need the ability to expose crypto capabilities as well as a key > eviction function. And those are currently handled by > "struct blk_keyslot_manager". Hence the need for a "passthrough keyslot > manager" that does those other things but not the actual keyslot management. > > FWIW, I suggested splitting these up, but you disagreed and said you wanted the > crypto capabilities to remain part of the blk_keyslot_manager > (https://lkml.kernel.org/linux-block/20200327170047.GA24682@infradead.org/). > If you've now changed your mind, please be clear about it. > I thought what Christoph meant (and of course, please let us know if I'm misunderstanding you, Christoph) was that if blk-mq handled all the blk-crypto stuff including deciding whether to use the blk-crypto-fallback, and blk-mq was responsible for calling out to blk-crypto-fallback if required, then the device mapper wouldn't need to expose any capabilities at all... or at least not for bio-based device mapper devices, since bios would go through the device mapper and eventually hit blk-mq which would then handle crypto appropriately. We couldn't do that because the crypto ciphers for the blk-crypto-fallback couldn't be allocated on the data path (so we needed fscrypt to ask blk-crypto to check whether the underlying device supported the crypto capabilities it required, and allocate ciphers appropriately, before the data path required the ciphers). I'm checking to see if anything has changed w.r.t allocating crypto ciphers on the data path (and checking if memalloc_noio_save/restore() helps with that). > - Eric
On Thu, Oct 15, 2020 at 09:46:29PM +0000, Satya Tangirala wrote: > +/** > + * blk_ksm_init_passthrough() - Init a passthrough keyslot manager > + * @ksm: The keyslot manager to init > + * > + * Initialize a passthrough keyslot manager. > + * Called by e.g. storage drivers to set up a keyslot manager in their > + * request_queue, when the storage driver wants to manage its keys by itself. > + * This is useful for inline encryption hardware that doesn't have the concept > + * of keyslots, and for layered devices. > + * > + * See blk_ksm_init() for more details about the parameters. > + */ > +void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm) > +{ > + memset(ksm, 0, sizeof(*ksm)); > + init_rwsem(&ksm->lock); > +} > +EXPORT_SYMBOL_GPL(blk_ksm_init_passthrough); The last paragraph of the comment ("See blk_ksm_init() for more details about the parameters.") isn't useful and should be removed. Otherwise this patch looks fine. You can add: Reviewed-by: Eric Biggers <ebiggers@google.com> - Eric
diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c index 35abcb1ec051..5ad476dafeab 100644 --- a/block/keyslot-manager.c +++ b/block/keyslot-manager.c @@ -62,6 +62,11 @@ static inline void blk_ksm_hw_exit(struct blk_keyslot_manager *ksm) pm_runtime_put_sync(ksm->dev); } +static inline bool blk_ksm_is_passthrough(struct blk_keyslot_manager *ksm) +{ + return ksm->num_slots == 0; +} + /** * blk_ksm_init() - Initialize a keyslot manager * @ksm: The keyslot_manager to initialize. @@ -198,6 +203,10 @@ blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm, int err; *slot_ptr = NULL; + + if (blk_ksm_is_passthrough(ksm)) + return BLK_STS_OK; + down_read(&ksm->lock); slot = blk_ksm_find_and_grab_keyslot(ksm, key); up_read(&ksm->lock); @@ -318,6 +327,16 @@ int blk_ksm_evict_key(struct blk_keyslot_manager *ksm, struct blk_ksm_keyslot *slot; int err = 0; + if (blk_ksm_is_passthrough(ksm)) { + if (ksm->ksm_ll_ops.keyslot_evict) { + blk_ksm_hw_enter(ksm); + err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, -1); + blk_ksm_hw_exit(ksm); + return err; + } + return 0; + } + blk_ksm_hw_enter(ksm); slot = blk_ksm_find_keyslot(ksm, key); if (!slot) @@ -353,6 +372,9 @@ void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm) { unsigned int slot; + if (blk_ksm_is_passthrough(ksm)) + return; + /* This is for device initialization, so don't resume the device */ down_write(&ksm->lock); for (slot = 0; slot < ksm->num_slots; slot++) { @@ -394,3 +416,22 @@ void blk_ksm_unregister(struct request_queue *q) { q->ksm = NULL; } + +/** + * blk_ksm_init_passthrough() - Init a passthrough keyslot manager + * @ksm: The keyslot manager to init + * + * Initialize a passthrough keyslot manager. + * Called by e.g. storage drivers to set up a keyslot manager in their + * request_queue, when the storage driver wants to manage its keys by itself. + * This is useful for inline encryption hardware that doesn't have the concept + * of keyslots, and for layered devices. + * + * See blk_ksm_init() for more details about the parameters. + */ +void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm) +{ + memset(ksm, 0, sizeof(*ksm)); + init_rwsem(&ksm->lock); +} +EXPORT_SYMBOL_GPL(blk_ksm_init_passthrough); diff --git a/include/linux/keyslot-manager.h b/include/linux/keyslot-manager.h index 18f3f5346843..323e15dd6fa7 100644 --- a/include/linux/keyslot-manager.h +++ b/include/linux/keyslot-manager.h @@ -103,4 +103,6 @@ void blk_ksm_reprogram_all_keys(struct blk_keyslot_manager *ksm); void blk_ksm_destroy(struct blk_keyslot_manager *ksm); +void blk_ksm_init_passthrough(struct blk_keyslot_manager *ksm); + #endif /* __LINUX_KEYSLOT_MANAGER_H */
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> --- block/keyslot-manager.c | 41 +++++++++++++++++++++++++++++++++ include/linux/keyslot-manager.h | 2 ++ 2 files changed, 43 insertions(+)