]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: quic: fix the header protection key length dump with AWS-LC
authorFrederic Lecaille <flecaille@haproxy.com>
Thu, 29 Oct 2026 13:49:16 +0000 (14:49 +0100)
committerFrederic Lecaille <flecaille@haproxy.com>
Tue, 3 Nov 2026 06:56:46 +0000 (07:56 +0100)
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
src/quic_tls.c

index 1332f85093f557876557385c69b8fa5893122a66..5cef804d0b0b2616e4dc0243ba153697859d15ce 100644 (file)
@@ -281,6 +281,25 @@ static inline const EVP_CIPHER *tls_hp(const SSL_CIPHER *cipher)
 
 }
 
+/* Return the key length of <hp>, 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)
index cab89916560ae50e41b1ee2a1f028d7f8109835f..2ef40c13dd197b5f3c9b81e87c53fe6a9afea579 100644 (file)
@@ -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;