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: 7+ 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
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox