From a90d760d572c37417db157901dc5c22a774048e9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 12 Jul 2026 22:36:52 -0400 Subject: blk-crypto: Simplify check for fallback support Since blk-crypto-fallback supports all blk_crypto_keys except wrapped keys, just check for that condition directly instead of using __blk_crypto_cfg_supported(). With this done, __blk_crypto_cfg_supported() is now used only for the hardware support. Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20260713023708.9245-2-ebiggers@kernel.org Signed-off-by: Eric Biggers --- block/blk-crypto-fallback.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'block') diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c index 2a5c52ab74b4..2a8f40a65158 100644 --- a/block/blk-crypto-fallback.c +++ b/block/blk-crypto-fallback.c @@ -496,8 +496,7 @@ bool blk_crypto_fallback_bio_prep(struct bio *bio) return false; } - if (!__blk_crypto_cfg_supported(blk_crypto_fallback_profile, - &bc->bc_key->crypto_cfg)) { + if (bc->bc_key->crypto_cfg.key_type != BLK_CRYPTO_KEY_TYPE_RAW) { bio_endio_status(bio, BLK_STS_NOTSUPP); return false; } -- cgit v1.2.3 From 0ffa0da2e538f5edd215384fd86a734cb356af22 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 12 Jul 2026 22:36:53 -0400 Subject: blk-crypto: Fold __blk_crypto_cfg_supported() into its caller __blk_crypto_cfg_supported() is called only by blk_crypto_config_supported_natively(), so fold it in. Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20260713023708.9245-3-ebiggers@kernel.org Signed-off-by: Eric Biggers --- block/blk-crypto-internal.h | 3 --- block/blk-crypto-profile.c | 22 ---------------------- block/blk-crypto.c | 23 +++++++++++++++++++++-- 3 files changed, 21 insertions(+), 27 deletions(-) (limited to 'block') diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h index 742694213529..2c7a0446572a 100644 --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -80,9 +80,6 @@ void blk_crypto_put_keyslot(struct blk_crypto_keyslot *slot); int __blk_crypto_evict_key(struct blk_crypto_profile *profile, const struct blk_crypto_key *key); -bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, - const struct blk_crypto_config *cfg); - int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd, void __user *argp); diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index cf447ba4a66e..53126c091b0b 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -335,28 +335,6 @@ void blk_crypto_put_keyslot(struct blk_crypto_keyslot *slot) } } -/** - * __blk_crypto_cfg_supported() - Check whether the given crypto profile - * supports the given crypto configuration. - * @profile: the crypto profile to check - * @cfg: the crypto configuration to check for - * - * Return: %true if @profile supports the given @cfg. - */ -bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, - const struct blk_crypto_config *cfg) -{ - if (!profile) - return false; - if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size)) - return false; - if (profile->max_dun_bytes_supported < cfg->dun_bytes) - return false; - if (!(profile->key_types_supported & cfg->key_type)) - return false; - return true; -} - /* * This is an internal function that evicts a key from an inline encryption * device that can be either a real device or the blk-crypto-fallback "device". diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 15e25e41b166..de60f03b4d4b 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -351,11 +351,30 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, } EXPORT_SYMBOL_GPL(blk_crypto_init_key); +/** + * blk_crypto_config_supported_natively() - Check whether a block device + * supports hardware inline encryption + * with the given configuration. + * @bdev: the block device + * @cfg: the crypto configuration to check for + * + * Return: %true if @bdev supports hardware inline encryption with @cfg. + */ bool blk_crypto_config_supported_natively(struct block_device *bdev, const struct blk_crypto_config *cfg) { - return __blk_crypto_cfg_supported(bdev_get_queue(bdev)->crypto_profile, - cfg); + struct blk_crypto_profile *profile = + bdev_get_queue(bdev)->crypto_profile; + + if (!profile) + return false; + if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size)) + return false; + if (profile->max_dun_bytes_supported < cfg->dun_bytes) + return false; + if (!(profile->key_types_supported & cfg->key_type)) + return false; + return true; } /* -- cgit v1.2.3 From 95b39df0413077b631cde9c6e35224c15258ccf5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 12 Jul 2026 22:36:54 -0400 Subject: blk-crypto: Allow control over whether hardware is used fscrypt uses inline encryption hardware only when the "inlinecrypt" mount option is given. I'd like to keep that behavior even after standardizing on the blk-crypto API for file contents encryption. That is, the default should continue to be the well-tested CPU-based encryption code, and the use of inline encryption hardware should continue to be an opt-in feature for systems where it's beneficial and has been fully validated (including verifying ciphertext correctness). To support this use case, extend blk_crypto_config with a new flag BLK_CRYPTO_CFG_ALLOW_HW. For now it's always set. Later commits will change that. Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20260713023708.9245-4-ebiggers@kernel.org Signed-off-by: Eric Biggers --- block/blk-crypto.c | 11 ++++++++++- drivers/md/dm-inlinecrypt.c | 3 ++- fs/crypto/inline_crypt.c | 4 +++- include/linux/blk-crypto.h | 13 ++++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) (limited to 'block') diff --git a/block/blk-crypto.c b/block/blk-crypto.c index de60f03b4d4b..0fe6ef0eea1d 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -300,6 +300,7 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, * @dun_bytes: number of bytes that will be used to specify the DUN when this * key is used * @data_unit_size: the data unit size to use for en/decryption + * @flags: BLK_CRYPTO_CFG_* flags * * Return: 0 on success, -errno on failure. The caller is responsible for * zeroizing both blk_key and key_bytes when done with them. @@ -309,7 +310,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size) + unsigned int data_unit_size, int flags) { const struct blk_crypto_mode *mode; @@ -318,6 +319,9 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, if (crypto_mode >= ARRAY_SIZE(blk_crypto_modes)) return -EINVAL; + if (flags & ~BLK_CRYPTO_CFG_ALLOW_HW) + return -EINVAL; + mode = &blk_crypto_modes[crypto_mode]; switch (key_type) { case BLK_CRYPTO_KEY_TYPE_RAW: @@ -328,6 +332,8 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, if (key_size < mode->security_strength || key_size > BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE) return -EINVAL; + if (!(flags & BLK_CRYPTO_CFG_ALLOW_HW)) + return -EINVAL; break; default: return -EINVAL; @@ -343,6 +349,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, blk_key->crypto_cfg.dun_bytes = dun_bytes; blk_key->crypto_cfg.data_unit_size = data_unit_size; blk_key->crypto_cfg.key_type = key_type; + blk_key->crypto_cfg.flags = flags; blk_key->data_unit_size_bits = ilog2(data_unit_size); blk_key->size = key_size; memcpy(blk_key->bytes, key_bytes, key_size); @@ -368,6 +375,8 @@ bool blk_crypto_config_supported_natively(struct block_device *bdev, if (!profile) return false; + if (!(cfg->flags & BLK_CRYPTO_CFG_ALLOW_HW)) + return false; if (!(profile->modes_supported[cfg->crypto_mode] & cfg->data_unit_size)) return false; if (profile->max_dun_bytes_supported < cfg->dun_bytes) diff --git a/drivers/md/dm-inlinecrypt.c b/drivers/md/dm-inlinecrypt.c index 41293c18d10f..f50970db0f94 100644 --- a/drivers/md/dm-inlinecrypt.c +++ b/drivers/md/dm-inlinecrypt.c @@ -408,7 +408,8 @@ static int inlinecrypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) err = blk_crypto_init_key(&ctx->key, key_bytes, ctx->key_size, ctx->key_type, cipher->mode_num, - dun_bytes, ctx->sector_size); + dun_bytes, ctx->sector_size, + BLK_CRYPTO_CFG_ALLOW_HW); if (err) { ti->error = "Error initializing blk-crypto key"; goto bad; diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 66b9c9150fed..013f2bdc6f23 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -126,6 +126,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci, crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci); crypto_cfg.key_type = is_hw_wrapped_key ? BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_RAW; + crypto_cfg.flags = BLK_CRYPTO_CFG_ALLOW_HW; num_devs = fscrypt_get_devices(sb, devs); for (i = 0; i < num_devs; i++) { @@ -162,7 +163,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, err = blk_crypto_init_key(blk_key, key_bytes, key_size, key_type, crypto_mode, fscrypt_get_dun_bytes(ci), - 1U << ci->ci_data_unit_bits); + 1U << ci->ci_data_unit_bits, + BLK_CRYPTO_CFG_ALLOW_HW); if (err) { fscrypt_err(inode, "error %d initializing blk-crypto key", err); goto fail; diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index f7c3cb4a342f..5f40821f99cd 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -68,6 +68,15 @@ enum blk_crypto_key_type { */ #define BLK_CRYPTO_SW_SECRET_SIZE 32 +/* Flags for blk_crypto_config::flags: */ + +/* + * If set, inline encryption hardware will be used if available. + * If unset, CPU-based encryption will always be used (requires + * CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) + */ +#define BLK_CRYPTO_CFG_ALLOW_HW (1 << 0) + /** * struct blk_crypto_config - an inline encryption key's crypto configuration * @crypto_mode: encryption algorithm this key is for @@ -77,12 +86,14 @@ enum blk_crypto_key_type { * filesystem block size or the disk sector size. * @dun_bytes: the maximum number of bytes of DUN used when using this key * @key_type: the type of this key -- either raw or hardware-wrapped + * @flags: BLK_CRYPTO_CFG_* flags */ struct blk_crypto_config { enum blk_crypto_mode_num crypto_mode; unsigned int data_unit_size; unsigned int dun_bytes; enum blk_crypto_key_type key_type; + int flags; }; /** @@ -150,7 +161,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, - unsigned int data_unit_size); + unsigned int data_unit_size, int flags); int blk_crypto_start_using_key(struct block_device *bdev, const struct blk_crypto_key *key); -- cgit v1.2.3 From fae2c34252cf4aea40d0d74fb41261bdcc581dbb Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 18 Jul 2026 14:46:54 -0700 Subject: blk-crypto: Remove unused function blk_crypto_config_supported() blk_crypto_config_supported() is no longer called, so remove it. Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20260718214655.63186-6-ebiggers@kernel.org Signed-off-by: Eric Biggers --- Documentation/block/inline-encryption.rst | 29 ++++++++++------------------- block/blk-crypto.c | 14 -------------- include/linux/blk-crypto.h | 2 -- 3 files changed, 10 insertions(+), 35 deletions(-) (limited to 'block') diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst index cae23949a626..0052c7011b48 100644 --- a/Documentation/block/inline-encryption.rst +++ b/Documentation/block/inline-encryption.rst @@ -185,20 +185,12 @@ blk-crypto-fallback is optional and is controlled by the API presented to users of the block layer ========================================= -``blk_crypto_config_supported()`` allows users to check ahead of time whether -inline encryption with particular crypto settings will work on a particular -block_device -- either via hardware or via blk-crypto-fallback. This function -takes in a ``struct blk_crypto_config`` which is like blk_crypto_key, but omits -the actual bytes of the key and instead just contains the algorithm, data unit -size, etc. This function can be useful if blk-crypto-fallback is disabled. - ``blk_crypto_init_key()`` allows users to initialize a blk_crypto_key. Users must call ``blk_crypto_start_using_key()`` before actually starting to use -a blk_crypto_key on a block_device (even if ``blk_crypto_config_supported()`` -was called earlier). This is needed to initialize blk-crypto-fallback if it -will be needed. This must not be called from the data path, as this may have to -allocate resources, which may deadlock in that case. +a blk_crypto_key on a block_device. This is needed to initialize +blk-crypto-fallback if it will be needed. This must not be called from the data +path, as this may have to allocate resources, which may deadlock in that case. Next, to attach an encryption context to a bio, users should call ``bio_crypt_set_ctx()``. This function allocates a bio_crypt_ctx and attaches @@ -220,16 +212,15 @@ any kernel data structures it may be linked into. In summary, for users of the block layer, the lifecycle of a blk_crypto_key is as follows: -1. ``blk_crypto_config_supported()`` (optional) -2. ``blk_crypto_init_key()`` -3. ``blk_crypto_start_using_key()`` -4. ``bio_crypt_set_ctx()`` (potentially many times) -5. ``blk_crypto_evict_key()`` (after all I/O has completed) -6. Zeroize the blk_crypto_key (this has no dedicated function) +1. ``blk_crypto_init_key()`` +2. ``blk_crypto_start_using_key()`` +3. ``bio_crypt_set_ctx()`` (potentially many times) +4. ``blk_crypto_evict_key()`` (after all I/O has completed) +5. Zeroize the blk_crypto_key (this has no dedicated function) If a blk_crypto_key is being used on multiple block_devices, then -``blk_crypto_config_supported()`` (if used), ``blk_crypto_start_using_key()``, -and ``blk_crypto_evict_key()`` must be called on each block_device. +``blk_crypto_start_using_key()`` and ``blk_crypto_evict_key()`` must be called +on each block_device. API presented to device drivers =============================== diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 0fe6ef0eea1d..bc3a9f59574b 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -386,20 +386,6 @@ bool blk_crypto_config_supported_natively(struct block_device *bdev, return true; } -/* - * Check if bios with @cfg can be en/decrypted by blk-crypto (i.e. either the - * block_device it's submitted to supports inline crypto, or the - * blk-crypto-fallback is enabled and supports the cfg). - */ -bool blk_crypto_config_supported(struct block_device *bdev, - const struct blk_crypto_config *cfg) -{ - if (IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) && - cfg->key_type == BLK_CRYPTO_KEY_TYPE_RAW) - return true; - return blk_crypto_config_supported_natively(bdev, cfg); -} - /** * blk_crypto_start_using_key() - Start using a blk_crypto_key on a device * @bdev: block device to operate on diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 5f40821f99cd..938ff536838c 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -171,8 +171,6 @@ void blk_crypto_evict_key(struct block_device *bdev, bool blk_crypto_config_supported_natively(struct block_device *bdev, const struct blk_crypto_config *cfg); -bool blk_crypto_config_supported(struct block_device *bdev, - const struct blk_crypto_config *cfg); int blk_crypto_derive_sw_secret(struct block_device *bdev, const u8 *eph_key, size_t eph_key_size, -- cgit v1.2.3