From: "Jason A. Donenfeld" <Jason@zx2c4.com>
To: Linus Torvalds <torvalds@linux-foundation.org>,
Eric Biggers <ebiggers@kernel.org>,
Ard Biesheuvel <ardb@kernel.org>, Kees Cook <kees@kernel.org>,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Subject: [PATCH libcrypto 2/2] crypto: chacha20poly1305: statically check fixed array lengths
Date: Tue, 18 Nov 2025 18:02:40 +0100 [thread overview]
Message-ID: <20251118170240.689299-2-Jason@zx2c4.com> (raw)
In-Reply-To: <20251118170240.689299-1-Jason@zx2c4.com>
Several parameters of the chacha20poly1305 functions require arrays of
an exact length. Use the new min_array_size() macro 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:
diff --git a/drivers/net/wireguard/cookie.h b/drivers/net/wireguard/cookie.h
index c4bd61ca03f2..2839c46029f8 100644
--- a/drivers/net/wireguard/cookie.h
+++ b/drivers/net/wireguard/cookie.h
@@ -13,7 +13,7 @@ struct wg_peer;
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];
u64 secret_birthdate;
struct rw_semaphore secret_lock;
If I try compiling this code, I get this nasty 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:29:6: note: in a call to function ‘xchacha20poly1305_encrypt’
29 | void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
This is exactly what's expected.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
include/crypto/chacha20poly1305.h | 17 +++++++++--------
lib/crypto/chacha20poly1305.c | 18 +++++++++---------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/crypto/chacha20poly1305.h b/include/crypto/chacha20poly1305.h
index d2ac3ff7dc1e..b19975f07d2f 100644
--- a/include/crypto/chacha20poly1305.h
+++ b/include/crypto/chacha20poly1305.h
@@ -6,6 +6,7 @@
#ifndef __CHACHA20POLY1305_H
#define __CHACHA20POLY1305_H
+#include <linux/array_size.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
@@ -18,32 +19,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[min_array_size(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[min_array_size(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[min_array_size(XCHACHA20POLY1305_NONCE_SIZE)],
+ const u8 key[min_array_size(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[min_array_size(XCHACHA20POLY1305_NONCE_SIZE)],
+ const u8 key[min_array_size(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[min_array_size(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[min_array_size(CHACHA20POLY1305_KEY_SIZE)]);
bool chacha20poly1305_selftest(void);
diff --git a/lib/crypto/chacha20poly1305.c b/lib/crypto/chacha20poly1305.c
index 0b49d6aedefd..5916d3bb694c 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[min_array_size(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[min_array_size(XCHACHA20POLY1305_NONCE_SIZE)],
+ const u8 key[min_array_size(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[min_array_size(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[min_array_size(XCHACHA20POLY1305_NONCE_SIZE)],
+ const u8 key[min_array_size(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[min_array_size(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[min_array_size(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[min_array_size(CHACHA20POLY1305_KEY_SIZE)])
{
if (unlikely(src_len < POLY1305_DIGEST_SIZE))
return false;
--
2.51.2
next prev parent reply other threads:[~2025-11-18 17:03 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-18 17:02 [PATCH libcrypto 1/2] array_size: introduce min_array_size() function decoration Jason A. Donenfeld
2025-11-18 17:02 ` Jason A. Donenfeld [this message]
2025-11-19 10:36 ` [PATCH libcrypto 2/2] crypto: chacha20poly1305: statically check fixed array lengths kernel test robot
2025-11-19 12:45 ` kernel test robot
2025-11-19 16:22 ` Linus Torvalds
2025-11-19 16:46 ` Jason A. Donenfeld
2025-11-19 16:57 ` Linus Torvalds
2025-11-19 18:45 ` Nathan Chancellor
2025-11-18 23:24 ` [PATCH libcrypto 1/2] array_size: introduce min_array_size() function decoration Eric Biggers
2025-11-18 23:31 ` Jason A. Donenfeld
2025-11-19 19:04 ` Jason A. Donenfeld
2025-11-19 19:10 ` Ard Biesheuvel
2025-11-19 23:02 ` david laight
2025-11-18 23:32 ` Linus Torvalds
2025-11-22 2:37 ` Herbert Xu
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=20251118170240.689299-2-Jason@zx2c4.com \
--to=jason@zx2c4.com \
--cc=ardb@kernel.org \
--cc=ebiggers@kernel.org \
--cc=kees@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.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
all inboxes | Powered by JetHome®