From 528b4bc2a4d43e1eff0567f695b7dfd7dd1b4634 Mon Sep 17 00:00:00 2001 From: Frederic Lecaille Date: Thu, 29 Oct 2026 14:49:16 +0100 Subject: [PATCH] BUG/MINOR: quic: fix the header protection key length dump with AWS-LC Under QUIC_AEAD_API, tls_hp() returns EVP_CIPHER_CHACHA20, which is an EVP_AEAD cast to EVP_CIPHER. Applied to it, EVP_CIPHER_key_length() reads an unrelated field and returns 1 instead of 32, so quic_tls_keys_hexdump() only dumps one byte of the header protection key. quic_tls_derive_keys() has the same computation but is guarded by #ifdef QUIC_AEAD_API. Move that special case to a helper in quic_tls.h and use it for both. This only affects the trace output. Measured on AWS-LC 5.9.0: 1 instead of 32 for ChaCha20, AES-128 and AES-256 unaffected. Should be backported to all stable versions even if only the QUIC traces are impacted. --- include/haproxy/quic_tls.h | 19 +++++++++++++++++++ src/quic_tls.c | 13 ++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 1332f8509..5cef804d0 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -281,6 +281,25 @@ static inline const EVP_CIPHER *tls_hp(const SSL_CIPHER *cipher) } +/* Return the key length of , the header protection cipher. + * Under QUIC_AEAD_API, tls_hp() returns + * EVP_CIPHER_CHACHA20, which is not an EVP_CIPHER at all but an EVP_AEAD + * cast to that type, as the underlying SSL library does not expose a + * ChaCha20 cipher usable for header protection. Calling + * EVP_CIPHER_key_length() on it would read the field of an EVP_CIPHER + * inside an EVP_AEAD object, so handle this case first. + */ +static inline size_t quic_hp_key_len(const EVP_CIPHER *hp) +{ + if (!hp) + return 0; +#ifdef QUIC_AEAD_API + if (hp == EVP_CIPHER_CHACHA20) + return 32; +#endif + return (size_t)EVP_CIPHER_key_length(hp); +} + /* These following functions map TLS implementation encryption level to ours */ static inline struct quic_pktns **ssl_to_quic_pktns(struct quic_conn *qc, enum ssl_encryption_level_t level) diff --git a/src/quic_tls.c b/src/quic_tls.c index cab899165..2ef40c13d 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -66,7 +66,7 @@ void quic_tls_keys_hexdump(struct buffer *buf, return; aead_keylen = (size_t)QUIC_AEAD_key_length(secs->aead); aead_ivlen = (size_t)QUIC_AEAD_iv_length(secs->aead); - hp_len = (size_t)EVP_CIPHER_key_length(secs->hp); + hp_len = quic_hp_key_len(secs->hp); chunk_appendf(buf, "\n key="); for (i = 0; i < aead_keylen; i++) @@ -541,16 +541,7 @@ int quic_tls_derive_keys(const QUIC_AEAD *aead, const EVP_CIPHER *hp, { size_t aead_keylen = (size_t)QUIC_AEAD_key_length(aead); size_t aead_ivlen = (size_t)QUIC_AEAD_iv_length(aead); -#ifdef QUIC_AEAD_API - size_t hp_len = 0; - - if (hp == EVP_CIPHER_CHACHA20) - hp_len = 32; - else if (hp) - hp_len = (size_t)EVP_CIPHER_key_length(hp); -#else - size_t hp_len = hp ? (size_t)EVP_CIPHER_key_length(hp) : 0; -#endif + size_t hp_len = quic_hp_key_len(hp); if (aead_keylen > keylen || aead_ivlen > ivlen || hp_len > hp_keylen) return 0; -- 2.47.3