lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAMj1kXGtDxf+GWx8xNQZcdvqfgJ+xL8m3U3TCoOypTGw7_-t3Q@mail.gmail.com>
Date: Fri, 21 Nov 2025 12:04:12 +0100
From: Ard Biesheuvel <ardb@...nel.org>
To: "Jason A. Donenfeld" <Jason@...c4.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>, Eric Biggers <ebiggers@...nel.org>, 
	Kees Cook <kees@...nel.org>, linux-crypto@...r.kernel.org, 
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH libcrypto v2 3/3] crypto: chacha20poly1305: statically
 check fixed array lengths

On Thu, 20 Nov 2025 at 02:11, Jason A. Donenfeld <Jason@...c4.com> wrote:
>
> Several parameters of the chacha20poly1305 functions require arrays of
> an exact length. Use the new at_least keyword to instruct gcc and
> clang to statically check that the caller is passing an object of at
> least that length.
>
> Here it is in action, with this faulty patch to wireguard's cookie.h:
>
>      struct cookie_checker {
>         u8 secret[NOISE_HASH_LEN];
>     -   u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN];
>     +   u8 cookie_encryption_key[NOISE_SYMMETRIC_KEY_LEN - 1];
>         u8 message_mac1_key[NOISE_SYMMETRIC_KEY_LEN];
>
> If I try compiling this code, I get this helpful warning:
>
>   CC      drivers/net/wireguard/cookie.o
> drivers/net/wireguard/cookie.c: In function ‘wg_cookie_message_create’:
> drivers/net/wireguard/cookie.c:193:9: warning: ‘xchacha20poly1305_encrypt’ reading 32 bytes from a region of size 31 [-Wstringop-overread]
>   193 |         xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   194 |                                   macs->mac1, COOKIE_LEN, dst->nonce,
>       |                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   195 |                                   checker->cookie_encryption_key);
>       |                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/net/wireguard/cookie.c:193:9: note: referencing argument 7 of type ‘const u8 *’ {aka ‘const unsigned char *’}
> In file included from drivers/net/wireguard/messages.h:10,
>                  from drivers/net/wireguard/cookie.h:9,
>                  from drivers/net/wireguard/cookie.c:6:
> include/crypto/chacha20poly1305.h:28:6: note: in a call to function ‘xchacha20poly1305_encrypt’
>    28 | void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>
> Signed-off-by: Jason A. Donenfeld <Jason@...c4.com>
> ---
>  include/crypto/chacha20poly1305.h | 16 ++++++++--------
>  lib/crypto/chacha20poly1305.c     | 18 +++++++++---------
>  2 files changed, 17 insertions(+), 17 deletions(-)
>

Acked-by: Ard Biesheuvel <ardb@...nel.org>

> diff --git a/include/crypto/chacha20poly1305.h b/include/crypto/chacha20poly1305.h
> index d2ac3ff7dc1e..7617366f8218 100644
> --- a/include/crypto/chacha20poly1305.h
> +++ b/include/crypto/chacha20poly1305.h
> @@ -18,32 +18,32 @@ enum chacha20poly1305_lengths {
>  void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>                               const u8 *ad, const size_t ad_len,
>                               const u64 nonce,
> -                             const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +                             const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  bool __must_check
>  chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
>                          const u8 *ad, const size_t ad_len, const u64 nonce,
> -                        const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +                        const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>                                const u8 *ad, const size_t ad_len,
> -                              const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
> -                              const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +                              const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
> +                              const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  bool __must_check xchacha20poly1305_decrypt(
>         u8 *dst, const u8 *src, const size_t src_len, const u8 *ad,
> -       const size_t ad_len, const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
> -       const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +       const size_t ad_len, const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
> +       const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len,
>                                          const u8 *ad, const size_t ad_len,
>                                          const u64 nonce,
> -                                        const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +                                        const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len,
>                                          const u8 *ad, const size_t ad_len,
>                                          const u64 nonce,
> -                                        const u8 key[CHACHA20POLY1305_KEY_SIZE]);
> +                                        const u8 key[at_least CHACHA20POLY1305_KEY_SIZE]);
>
>  bool chacha20poly1305_selftest(void);
>
> diff --git a/lib/crypto/chacha20poly1305.c b/lib/crypto/chacha20poly1305.c
> index 0b49d6aedefd..212ce33562af 100644
> --- a/lib/crypto/chacha20poly1305.c
> +++ b/lib/crypto/chacha20poly1305.c
> @@ -89,7 +89,7 @@ __chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>  void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>                               const u8 *ad, const size_t ad_len,
>                               const u64 nonce,
> -                             const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                             const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         struct chacha_state chacha_state;
>         u32 k[CHACHA_KEY_WORDS];
> @@ -111,8 +111,8 @@ EXPORT_SYMBOL(chacha20poly1305_encrypt);
>
>  void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
>                                const u8 *ad, const size_t ad_len,
> -                              const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
> -                              const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                              const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
> +                              const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         struct chacha_state chacha_state;
>
> @@ -170,7 +170,7 @@ __chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
>  bool chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
>                               const u8 *ad, const size_t ad_len,
>                               const u64 nonce,
> -                             const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                             const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         struct chacha_state chacha_state;
>         u32 k[CHACHA_KEY_WORDS];
> @@ -195,8 +195,8 @@ EXPORT_SYMBOL(chacha20poly1305_decrypt);
>
>  bool xchacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len,
>                                const u8 *ad, const size_t ad_len,
> -                              const u8 nonce[XCHACHA20POLY1305_NONCE_SIZE],
> -                              const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                              const u8 nonce[at_least XCHACHA20POLY1305_NONCE_SIZE],
> +                              const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         struct chacha_state chacha_state;
>
> @@ -211,7 +211,7 @@ bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src,
>                                        const size_t src_len,
>                                        const u8 *ad, const size_t ad_len,
>                                        const u64 nonce,
> -                                      const u8 key[CHACHA20POLY1305_KEY_SIZE],
> +                                      const u8 key[at_least CHACHA20POLY1305_KEY_SIZE],
>                                        int encrypt)
>  {
>         const u8 *pad0 = page_address(ZERO_PAGE(0));
> @@ -335,7 +335,7 @@ bool chacha20poly1305_crypt_sg_inplace(struct scatterlist *src,
>  bool chacha20poly1305_encrypt_sg_inplace(struct scatterlist *src, size_t src_len,
>                                          const u8 *ad, const size_t ad_len,
>                                          const u64 nonce,
> -                                        const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                                        const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         return chacha20poly1305_crypt_sg_inplace(src, src_len, ad, ad_len,
>                                                  nonce, key, 1);
> @@ -345,7 +345,7 @@ EXPORT_SYMBOL(chacha20poly1305_encrypt_sg_inplace);
>  bool chacha20poly1305_decrypt_sg_inplace(struct scatterlist *src, size_t src_len,
>                                          const u8 *ad, const size_t ad_len,
>                                          const u64 nonce,
> -                                        const u8 key[CHACHA20POLY1305_KEY_SIZE])
> +                                        const u8 key[at_least CHACHA20POLY1305_KEY_SIZE])
>  {
>         if (unlikely(src_len < POLY1305_DIGEST_SIZE))
>                 return false;
> --
> 2.52.0
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ