]> www.infradead.org Git - users/willy/xarray.git/commitdiff
dm-crypt: switch to using the crc32 library
authorEric Biggers <ebiggers@google.com>
Mon, 27 Jan 2025 22:15:33 +0000 (14:15 -0800)
committerMikulas Patocka <mpatocka@redhat.com>
Mon, 3 Feb 2025 13:10:10 +0000 (14:10 +0100)
Now that the crc32() library function takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API.  Just use crc32().  This is much simpler, and it improves
performance due to eliminating the crypto API overhead.  (However, this
only affects the TCW IV mode of dm-crypt, which is a compatibility mode
that is rarely used compared to other dm-crypt modes.)

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
drivers/md/Kconfig
drivers/md/dm-crypt.c

index 0b1870a09e1fdc1384329b083496e25e664563a4..06f809e70f1535426d4a5109e29cc52a096a6d76 100644 (file)
@@ -267,6 +267,7 @@ config DM_CRYPT
        depends on BLK_DEV_DM
        depends on (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n)
        depends on (TRUSTED_KEYS || TRUSTED_KEYS=n)
+       select CRC32
        select CRYPTO
        select CRYPTO_CBC
        select CRYPTO_ESSIV
index 02a2919f4e5aad9f5e9abdb7210657e43068ffba..9dfdb63220d746241d4d490058dc1ef6c374811c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/blk-integrity.h>
+#include <linux/crc32.h>
 #include <linux/mempool.h>
 #include <linux/slab.h>
 #include <linux/crypto.h>
@@ -125,7 +126,6 @@ struct iv_lmk_private {
 
 #define TCW_WHITENING_SIZE 16
 struct iv_tcw_private {
-       struct crypto_shash *crc32_tfm;
        u8 *iv_seed;
        u8 *whitening;
 };
@@ -607,10 +607,6 @@ static void crypt_iv_tcw_dtr(struct crypt_config *cc)
        tcw->iv_seed = NULL;
        kfree_sensitive(tcw->whitening);
        tcw->whitening = NULL;
-
-       if (tcw->crc32_tfm && !IS_ERR(tcw->crc32_tfm))
-               crypto_free_shash(tcw->crc32_tfm);
-       tcw->crc32_tfm = NULL;
 }
 
 static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
@@ -628,13 +624,6 @@ static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
                return -EINVAL;
        }
 
-       tcw->crc32_tfm = crypto_alloc_shash("crc32", 0,
-                                           CRYPTO_ALG_ALLOCATES_MEMORY);
-       if (IS_ERR(tcw->crc32_tfm)) {
-               ti->error = "Error initializing CRC32 in TCW";
-               return PTR_ERR(tcw->crc32_tfm);
-       }
-
        tcw->iv_seed = kzalloc(cc->iv_size, GFP_KERNEL);
        tcw->whitening = kzalloc(TCW_WHITENING_SIZE, GFP_KERNEL);
        if (!tcw->iv_seed || !tcw->whitening) {
@@ -668,36 +657,28 @@ static int crypt_iv_tcw_wipe(struct crypt_config *cc)
        return 0;
 }
 
-static int crypt_iv_tcw_whitening(struct crypt_config *cc,
-                                 struct dm_crypt_request *dmreq,
-                                 u8 *data)
+static void crypt_iv_tcw_whitening(struct crypt_config *cc,
+                                  struct dm_crypt_request *dmreq, u8 *data)
 {
        struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
        __le64 sector = cpu_to_le64(dmreq->iv_sector);
        u8 buf[TCW_WHITENING_SIZE];
-       SHASH_DESC_ON_STACK(desc, tcw->crc32_tfm);
-       int i, r;
+       int i;
 
        /* xor whitening with sector number */
        crypto_xor_cpy(buf, tcw->whitening, (u8 *)&sector, 8);
        crypto_xor_cpy(&buf[8], tcw->whitening + 8, (u8 *)&sector, 8);
 
        /* calculate crc32 for every 32bit part and xor it */
-       desc->tfm = tcw->crc32_tfm;
-       for (i = 0; i < 4; i++) {
-               r = crypto_shash_digest(desc, &buf[i * 4], 4, &buf[i * 4]);
-               if (r)
-                       goto out;
-       }
+       for (i = 0; i < 4; i++)
+               put_unaligned_le32(crc32(0, &buf[i * 4], 4), &buf[i * 4]);
        crypto_xor(&buf[0], &buf[12], 4);
        crypto_xor(&buf[4], &buf[8], 4);
 
        /* apply whitening (8 bytes) to whole sector */
        for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++)
                crypto_xor(data + i * 8, buf, 8);
-out:
        memzero_explicit(buf, sizeof(buf));
-       return r;
 }
 
 static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
@@ -707,13 +688,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
        struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
        __le64 sector = cpu_to_le64(dmreq->iv_sector);
        u8 *src;
-       int r = 0;
 
        /* Remove whitening from ciphertext */
        if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) {
                sg = crypt_get_sg_data(cc, dmreq->sg_in);
                src = kmap_local_page(sg_page(sg));
-               r = crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset);
+               crypt_iv_tcw_whitening(cc, dmreq, src + sg->offset);
                kunmap_local(src);
        }
 
@@ -723,7 +703,7 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
                crypto_xor_cpy(&iv[8], tcw->iv_seed + 8, (u8 *)&sector,
                               cc->iv_size - 8);
 
-       return r;
+       return 0;
 }
 
 static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
@@ -731,7 +711,6 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
 {
        struct scatterlist *sg;
        u8 *dst;
-       int r;
 
        if (bio_data_dir(dmreq->ctx->bio_in) != WRITE)
                return 0;
@@ -739,10 +718,10 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
        /* Apply whitening on ciphertext */
        sg = crypt_get_sg_data(cc, dmreq->sg_out);
        dst = kmap_local_page(sg_page(sg));
-       r = crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset);
+       crypt_iv_tcw_whitening(cc, dmreq, dst + sg->offset);
        kunmap_local(dst);
 
-       return r;
+       return 0;
 }
 
 static int crypt_iv_random_gen(struct crypt_config *cc, u8 *iv,