]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic: use ha_random64_pair_hashed() to generate the QUIC retry tokens
authorWilly Tarreau <w@1wt.eu>
Mon, 25 May 2026 16:31:02 +0000 (18:31 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 26 May 2026 11:13:24 +0000 (13:13 +0200)
The QUIC retry tokens used to directly return ha_random64(), making the
next tokens easily predictable on low-load systems before the XXH64 call.
Let's now switch to the faster and safer ha_random64_pair_hashed() instead.

src/quic_token.c

index 5200225ef08a04a1808d816cd00f5ad3a294f2ef..2ac5458af4c4cbe198cc29e23bcaf35c7adde7f3 100644 (file)
@@ -24,8 +24,10 @@ int quic_generate_token(unsigned char *token, size_t len,
        unsigned char aad[sizeof(struct in6_addr)];
        size_t aadlen;
        uint32_t ts = (uint32_t)date.tv_sec;
-       uint64_t rand_u64;
-       unsigned char rand[QUIC_TOKEN_RAND_DLEN];
+       union {
+               uint64_t u64[2];
+               uchar u8[QUIC_TOKEN_RAND_DLEN];
+       } rand;
        unsigned char key[16];
        unsigned char iv[QUIC_TLS_IV_LEN];
        const unsigned char *sec = global.cluster_secret;
@@ -35,10 +37,7 @@ int quic_generate_token(unsigned char *token, size_t len,
        TRACE_ENTER(QUIC_EV_CONN_TXPKT);
 
        /* Generate random data to be used as salt to derive the token secret. */
-       rand_u64 = ha_random64();
-       write_u64(rand, rand_u64);
-       rand_u64 = ha_random64();
-       write_u64(rand + sizeof(rand_u64), rand_u64);
+       ha_random64_pair_hashed(&rand.u64[0], &rand.u64[1]);
 
        if (len < QUIC_TOKEN_LEN) {
                TRACE_ERROR("too small buffer", QUIC_EV_CONN_TXPKT);
@@ -48,7 +47,7 @@ int quic_generate_token(unsigned char *token, size_t len,
        /* Generate the AAD. */
        aadlen = ipaddrcpy(aad, addr);
        if (!quic_tls_derive_token_secret(EVP_sha256(), key, sizeof key,
-                                         iv, sizeof iv, rand, sizeof(rand),
+                                         iv, sizeof iv, rand.u8, sizeof(rand.u8),
                                          sec, seclen)) {
                TRACE_ERROR("quic_tls_derive_token_secret() failed", QUIC_EV_CONN_TXPKT);
                goto err;
@@ -71,8 +70,8 @@ int quic_generate_token(unsigned char *token, size_t len,
        }
 
        p += QUIC_TLS_TAG_LEN;
-       memcpy(p, rand, sizeof(rand));
-       p += sizeof(rand);
+       memcpy(p, rand.u8, sizeof(rand.u8));
+       p += sizeof(rand.u8);
 
        ret = p - token;
  leave: