]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: drbg - Fix misaligned writes in CTR_DRBG and HASH_DRBG
authorEric Biggers <ebiggers@kernel.org>
Mon, 20 Apr 2026 06:33:46 +0000 (23:33 -0700)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 7 May 2026 08:09:59 +0000 (16:09 +0800)
drbg_cpu_to_be32() is being used to do a plain write to a byte array,
which doesn't have any alignment guarantee.  This can cause a misaligned
write.  Replace it with the correct function, put_unaligned_be32().

Fixes: 72f3e00dd67e ("crypto: drbg - replace int2byte with cpu_to_be")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/df_sp80090a.c
crypto/drbg.c
include/crypto/internal/drbg.h

index b8134be6f7ad9f3bef3d22a5b785ae6a59b214ad..f4bb7be016e850364b8b075622933a3b164d8b09 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/df_sp80090a.h>
 #include <crypto/internal/drbg.h>
@@ -141,10 +142,10 @@ int crypto_drbg_ctr_df(struct aes_enckey *aeskey,
        /* 10.4.2 step 2 -- calculate the entire length of all input data */
        list_for_each_entry(seed, seedlist, list)
                inputlen += seed->len;
-       drbg_cpu_to_be32(inputlen, &L_N[0]);
+       put_unaligned_be32(inputlen, &L_N[0]);
 
        /* 10.4.2 step 3 */
-       drbg_cpu_to_be32(bytes_to_return, &L_N[4]);
+       put_unaligned_be32(bytes_to_return, &L_N[4]);
 
        /* 10.4.2 step 5: length is L_N, input_string, one byte, padding */
        padlen = (inputlen + sizeof(L_N) + 1) % (blocklen_bytes);
@@ -175,7 +176,7 @@ int crypto_drbg_ctr_df(struct aes_enckey *aeskey,
                 * holds zeros after allocation -- even the increment of i
                 * is irrelevant as the increment remains within length of i
                 */
-               drbg_cpu_to_be32(i, iv);
+               put_unaligned_be32(i, iv);
                /* 10.4.2 step 9.2 -- BCC and concatenation with temp */
                drbg_ctr_bcc(aeskey, temp + templen, K, &bcc_list,
                             blocklen_bytes, keylen);
index e4eb78ed222b9044abb1ef17eba38286e95990bb..de4c69032155ed6323ca182307b663aee6c337a5 100644 (file)
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/string_choices.h>
+#include <linux/unaligned.h>
 
 /***************************************************************
  * Backend cipher definitions available to DRBG
@@ -601,7 +602,7 @@ static int drbg_hash_df(struct drbg_state *drbg,
 
        /* 10.4.1 step 3 */
        input[0] = 1;
-       drbg_cpu_to_be32((outlen * 8), &input[1]);
+       put_unaligned_be32(outlen * 8, &input[1]);
 
        /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
        drbg_string_fill(&data, input, 5);
index 371e52dcee6c57bc826d1925b4423d60a09482fc..b4e5ef0be602f2579566a23088d9b12fe88a0582 100644 (file)
@@ -9,24 +9,6 @@
 #ifndef _INTERNAL_DRBG_H
 #define _INTERNAL_DRBG_H
 
-/*
- * Convert an integer into a byte representation of this integer.
- * The byte representation is big-endian
- *
- * @val value to be converted
- * @buf buffer holding the converted integer -- caller must ensure that
- *      buffer size is at least 32 bit
- */
-static inline void drbg_cpu_to_be32(__u32 val, unsigned char *buf)
-{
-       struct s {
-               __be32 conv;
-       };
-       struct s *conversion = (struct s *)buf;
-
-       conversion->conv = cpu_to_be32(val);
-}
-
 /*
  * Concatenation Helper and string operation helper
  *