Commit 6d621e6729 for openssl.org

commit 6d621e6729d41a809d87c221728d11a52d913a13
Author: Alexandr Nedvedicky <sashan@openssl.org>
Date:   Wed Jan 28 08:03:18 2026 +0100

    QUIC LCID hash table collapse on Windows/32-bit due to SipHash digest size misuse

    Using sizeof(unsigned long) as SipHash digest size; SipHash supports
    only 8 or 16 bytes. On platforms where sizeof(unsigned long) == 4,
    the call fails, and lcid_hash returns the zero-initialized value,
    degrading the hash table into list.

    The issue was kindly reported and fix provided by Stanislav Fort at Aisle Research.

    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Neil Horman <nhorman@openssl.org>
    MergeDate: Thu Mar 12 18:04:10 2026
    (Merged from https://github.com/openssl/openssl/pull/29814)

diff --git a/ssl/quic/quic_lcidm.c b/ssl/quic/quic_lcidm.c
index 660eb802ba..e23c16ce44 100644
--- a/ssl/quic/quic_lcidm.c
+++ b/ssl/quic/quic_lcidm.c
@@ -74,15 +74,21 @@ static unsigned long lcid_hash(const QUIC_LCID *lcid_obj)
         0,
     };
     unsigned long hashval = 0;
+    unsigned char digest[SIPHASH_MIN_DIGEST_SIZE];

-    if (!SipHash_set_hash_size(&siphash, sizeof(unsigned long)))
+    /* Use a supported SipHash digest size (8 or 16); 8 is sufficient here. */
+    if (!SipHash_set_hash_size(&siphash, SIPHASH_MIN_DIGEST_SIZE))
         goto out;
     if (!SipHash_Init(&siphash, (uint8_t *)lcid_obj->hash_key, 0, 0))
         goto out;
     SipHash_Update(&siphash, lcid_obj->cid.id, lcid_obj->cid.id_len);
-    if (!SipHash_Final(&siphash, (unsigned char *)&hashval,
-            sizeof(unsigned long)))
+    if (!SipHash_Final(&siphash, digest, SIPHASH_MIN_DIGEST_SIZE))
         goto out;
+
+    /*
+     * Truncate the 64-bit SipHash digest into an unsigned long.
+     */
+    memcpy(&hashval, digest, sizeof(hashval) < sizeof(digest) ? sizeof(hashval) : sizeof(digest));
 out:
     return hashval;
 }