From: Leonid Ravich <lravich@amazon.com>
To: <linux-crypto@vger.kernel.org>, <dm-devel@lists.linux.dev>
Cc: <linux-block@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<herbert@gondor.apana.org.au>, <davem@davemloft.net>,
<ebiggers@kernel.org>, <snitzer@kernel.org>,
<mpatocka@redhat.com>, <axboe@kernel.dk>
Subject: [PATCH v5 5/5] blk-crypto: fallback - batch a segment's data units via dun()
Date: Wed, 1 Jul 2026 06:53:54 +0000 [thread overview]
Message-ID: <20260701065354.18928-1-lravich@amazon.com> (raw)
In-Reply-To: <20260630083431.2772-1-lravich@amazon.com>
blk-crypto-fallback open-codes a per-data-unit loop, issuing one
skcipher request per data unit with the IV walked as a DUN counter.
Allocate dun(<cipher>,le) instead of the bare cipher so a contiguous bio
segment is encrypted/decrypted as one multi-data-unit request, the
crypto layer walking the per-unit IV. Every blk-crypto mode feeds the
DUN as a little-endian counter, and dun() handles any counter width up
to 32 bytes, so all modes -- including Adiantum (32-byte IV) -- are
wrapped and the open-coded inner per-unit loop is removed from both the
encrypt and decrypt paths. This makes blk-crypto-fallback a second
consumer of the template (after dm-crypt) and lets a higher-priority
hardware dun(...) driver, if present, handle the request in one pass.
Output is unchanged: the template's little-endian per-unit counter is
exactly blk_crypto_dun_to_iv()/bio_crypt_dun_increment().
Signed-off-by: Leonid Ravich <lravich@amazon.com>
---
block/Kconfig | 1 +
block/blk-crypto-fallback.c | 74 ++++++++++++++++++-------------------
2 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/block/Kconfig b/block/Kconfig
index 15027963472d..0c9025f9b0f6 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -204,6 +204,7 @@ config BLK_INLINE_ENCRYPTION_FALLBACK
depends on BLK_INLINE_ENCRYPTION
select CRYPTO
select CRYPTO_SKCIPHER
+ select CRYPTO_DUN # batches a segment's data units per crypto request
help
Enabling this lets the block layer handle inline encryption
by falling back to the kernel crypto API when inline
diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
index 61f595410832..8337d56ba1dc 100644
--- a/block/blk-crypto-fallback.c
+++ b/block/blk-crypto-fallback.c
@@ -250,7 +250,6 @@ static void __blk_crypto_fallback_encrypt_bio(struct bio *src_bio,
unsigned int nr_enc_pages, enc_idx;
struct page **enc_pages;
struct bio *enc_bio;
- unsigned int i;
skcipher_request_set_callback(ciph_req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
@@ -260,9 +259,6 @@ static void __blk_crypto_fallback_encrypt_bio(struct bio *src_bio,
sg_init_table(&src, 1);
sg_init_table(&dst, 1);
- skcipher_request_set_crypt(ciph_req, &src, &dst, data_unit_size,
- iv.bytes);
-
/*
* Encrypt each page in the source bio. Because the source bio could
* have bio_vecs that span more than a single page, but the encrypted
@@ -287,29 +283,26 @@ static void __blk_crypto_fallback_encrypt_bio(struct bio *src_bio,
__bio_add_page(enc_bio, enc_page, src_bv.bv_len,
src_bv.bv_offset);
- sg_set_page(&src, src_bv.bv_page, data_unit_size,
- src_bv.bv_offset);
- sg_set_page(&dst, enc_page, data_unit_size, src_bv.bv_offset);
-
/*
* Increment the index now that the encrypted page is added to
* the bio. This is important for the error unwind path.
*/
enc_idx++;
- /*
- * Encrypt each data unit in this page.
- */
- for (i = 0; i < src_bv.bv_len; i += data_unit_size) {
- blk_crypto_dun_to_iv(curr_dun, &iv);
- if (crypto_skcipher_encrypt(ciph_req)) {
- enc_bio->bi_status = BLK_STS_IOERR;
- goto out_free_enc_bio;
- }
- bio_crypt_dun_increment(curr_dun, 1);
- src.offset += data_unit_size;
- dst.offset += data_unit_size;
+ /* Encrypt the whole segment as one multi-data-unit request. */
+ blk_crypto_dun_to_iv(curr_dun, &iv);
+ sg_set_page(&src, src_bv.bv_page, src_bv.bv_len,
+ src_bv.bv_offset);
+ sg_set_page(&dst, enc_page, src_bv.bv_len, src_bv.bv_offset);
+ skcipher_request_set_crypt(ciph_req, &src, &dst, src_bv.bv_len,
+ iv.bytes);
+ skcipher_request_set_data_unit_size(ciph_req, data_unit_size);
+ if (crypto_skcipher_encrypt(ciph_req)) {
+ enc_bio->bi_status = BLK_STS_IOERR;
+ goto out_free_enc_bio;
}
+ bio_crypt_dun_increment(curr_dun,
+ src_bv.bv_len / data_unit_size);
bio_advance_iter_single(src_bio, &src_bio->bi_iter,
src_bv.bv_len);
@@ -380,7 +373,6 @@ static blk_status_t __blk_crypto_fallback_decrypt_bio(struct bio *bio,
struct scatterlist sg;
struct bio_vec bv;
const int data_unit_size = bc->bc_key->crypto_cfg.data_unit_size;
- unsigned int i;
skcipher_request_set_callback(ciph_req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
@@ -388,26 +380,20 @@ static blk_status_t __blk_crypto_fallback_decrypt_bio(struct bio *bio,
memcpy(curr_dun, bc->bc_dun, sizeof(curr_dun));
sg_init_table(&sg, 1);
- skcipher_request_set_crypt(ciph_req, &sg, &sg, data_unit_size,
- iv.bytes);
- /* Decrypt each segment in the bio */
+ /* One dun() request per segment; the crypto layer walks the per-unit DUN. */
__bio_for_each_segment(bv, bio, iter, iter) {
- struct page *page = bv.bv_page;
-
if (!IS_ALIGNED(bv.bv_len | bv.bv_offset, data_unit_size))
return BLK_STS_INVAL;
- sg_set_page(&sg, page, data_unit_size, bv.bv_offset);
-
- /* Decrypt each data unit in the segment */
- for (i = 0; i < bv.bv_len; i += data_unit_size) {
- blk_crypto_dun_to_iv(curr_dun, &iv);
- if (crypto_skcipher_decrypt(ciph_req))
- return BLK_STS_IOERR;
- bio_crypt_dun_increment(curr_dun, 1);
- sg.offset += data_unit_size;
- }
+ blk_crypto_dun_to_iv(curr_dun, &iv);
+ sg_set_page(&sg, bv.bv_page, bv.bv_len, bv.bv_offset);
+ skcipher_request_set_crypt(ciph_req, &sg, &sg, bv.bv_len,
+ iv.bytes);
+ skcipher_request_set_data_unit_size(ciph_req, data_unit_size);
+ if (crypto_skcipher_decrypt(ciph_req))
+ return BLK_STS_IOERR;
+ bio_crypt_dun_increment(curr_dun, bv.bv_len / data_unit_size);
}
return BLK_STS_OK;
@@ -621,6 +607,7 @@ static int blk_crypto_fallback_init(void)
int blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num)
{
const char *cipher_str = blk_crypto_modes[mode_num].cipher_str;
+ char dun_str[CRYPTO_MAX_ALG_NAME];
struct blk_crypto_fallback_keyslot *slotp;
unsigned int i;
int err = 0;
@@ -641,15 +628,24 @@ int blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num)
if (err)
goto out;
+ /*
+ * Wrap in dun() to handle a whole segment per request (a higher-priority
+ * hardware dun() wins if present). The blk-crypto DUN is little-endian.
+ */
+ if (snprintf(dun_str, sizeof(dun_str), "dun(%s,le)", cipher_str) >=
+ (int)sizeof(dun_str)) {
+ err = -EINVAL;
+ goto out;
+ }
+
for (i = 0; i < blk_crypto_num_keyslots; i++) {
slotp = &blk_crypto_keyslots[i];
- slotp->tfms[mode_num] = crypto_alloc_sync_skcipher(cipher_str,
- 0, 0);
+ slotp->tfms[mode_num] = crypto_alloc_sync_skcipher(dun_str, 0, 0);
if (IS_ERR(slotp->tfms[mode_num])) {
err = PTR_ERR(slotp->tfms[mode_num]);
if (err == -ENOENT) {
pr_warn_once("Missing crypto API support for \"%s\"\n",
- cipher_str);
+ dun_str);
err = -ENOPKG;
}
slotp->tfms[mode_num] = NULL;
--
2.47.3
next prev parent reply other threads:[~2026-07-01 6:54 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 8:34 [PATCH v5 0/5] crypto: skcipher - multi-data-unit dispatch as a template Leonid Ravich
2026-06-30 8:34 ` [PATCH v5 1/5] crypto: skcipher - add per-request data_unit_size Leonid Ravich
2026-06-30 8:34 ` [PATCH v5 2/5] crypto: dun - data-unit-number dispatch template Leonid Ravich
2026-06-30 8:34 ` [PATCH v5 3/5] crypto: testmgr - test dun() dispatch Leonid Ravich
2026-06-30 8:34 ` [PATCH v5 4/5] dm crypt: batch a bio segment's sectors via dun() Leonid Ravich
2026-07-01 6:53 ` Leonid Ravich [this message]
2026-07-01 7:19 ` [PATCH v5 0/5] crypto: skcipher - multi-data-unit dispatch as a template Eric Biggers
2026-07-02 8:45 ` Leonid Ravich
2026-07-02 16:45 ` Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701065354.18928-1-lravich@amazon.com \
--to=lravich@amazon.com \
--cc=axboe@kernel.dk \
--cc=davem@davemloft.net \
--cc=dm-devel@lists.linux.dev \
--cc=ebiggers@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-block@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mpatocka@redhat.com \
--cc=snitzer@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.