dm crypt: Avoid using MAX_CIPHER_BLOCKSIZE
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 1 Jun 2023 08:47:43 +0000 (16:47 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 9 Jun 2023 09:10:04 +0000 (17:10 +0800)
MAX_CIPHER_BLOCKSIZE is an internal implementation detail and should
not be relied on by users of the Crypto API.

Instead of storing the IV on the stack, allocate it together with
the crypto request.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Reviewed-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/md/dm-crypt.c

index 8b47b91..5b009bb 100644 (file)
 #include <asm/unaligned.h>
 #include <crypto/hash.h>
 #include <crypto/md5.h>
-#include <crypto/algapi.h>
 #include <crypto/skcipher.h>
 #include <crypto/aead.h>
 #include <crypto/authenc.h>
+#include <crypto/utils.h>
 #include <linux/rtnetlink.h> /* for struct rtattr and RTA macros only */
 #include <linux/key-type.h>
 #include <keys/user-type.h>
@@ -745,16 +745,23 @@ static int crypt_iv_eboiv_ctr(struct crypt_config *cc, struct dm_target *ti,
 static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
                            struct dm_crypt_request *dmreq)
 {
-       u8 buf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(__le64));
+       struct crypto_skcipher *tfm = any_tfm(cc);
        struct skcipher_request *req;
        struct scatterlist src, dst;
        DECLARE_CRYPTO_WAIT(wait);
+       unsigned int reqsize;
        int err;
+       u8 *buf;
 
-       req = skcipher_request_alloc(any_tfm(cc), GFP_NOIO);
+       reqsize = ALIGN(crypto_skcipher_reqsize(tfm), __alignof__(__le64));
+
+       req = kmalloc(reqsize + cc->iv_size, GFP_NOIO);
        if (!req)
                return -ENOMEM;
 
+       skcipher_request_set_tfm(req, tfm);
+
+       buf = (u8 *)req + reqsize;
        memset(buf, 0, cc->iv_size);
        *(__le64 *)buf = cpu_to_le64(dmreq->iv_sector * cc->sector_size);
 
@@ -763,7 +770,7 @@ static int crypt_iv_eboiv_gen(struct crypt_config *cc, u8 *iv,
        skcipher_request_set_crypt(req, &src, &dst, cc->iv_size, buf);
        skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
        err = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
-       skcipher_request_free(req);
+       kfree_sensitive(req);
 
        return err;
 }