From: Willy Tarreau Date: Mon, 25 May 2026 15:56:01 +0000 (+0200) Subject: MEDIUM: tools: use the hashed random pair for UUID generation X-Git-Tag: v3.4-dev14~23 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=85003563c5bbadd3f1197fb3f2801abb933566e3;p=thirdparty%2Fhaproxy.git MEDIUM: tools: use the hashed random pair for UUID generation The UUID generation used to emit the internal PRNG state, which allows to predict previous and next ones, or disclose the internal PRNG state. While not critical, it may eventually become an issue. This patch uses the new ha_random64_pair_hashed() function that returns a pair of u64 that are hashed from the internal PRNG state. It's almost twice as fast on 20 threads (14.1M UUID/s vs 7.8M/s). --- diff --git a/src/tools.c b/src/tools.c index f9825826d..2025790e2 100644 --- a/src/tools.c +++ b/src/tools.c @@ -6388,23 +6388,15 @@ void ha_random_jump96(uint32_t dist) */ void ha_generate_uuid_v4(struct buffer *output) { - uint32_t rnd[4]; - uint64_t last; - - last = ha_random64(); - rnd[0] = last; - rnd[1] = last >> 32; - - last = ha_random64(); - rnd[2] = last; - rnd[3] = last >> 32; + uint64_t l, h; + ha_random64_pair_hashed(&l, &h); chunk_printf(output, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx", - rnd[0], - rnd[1] & 0xFFFF, - ((rnd[1] >> 16u) & 0xFFF) | 0x4000, // highest 4 bits indicate the uuid version - (rnd[2] & 0x3FFF) | 0x8000, // the highest 2 bits indicate the UUID variant (10), - (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull); + (uint)l, + (uint)(l >> 32) & 0xFFFF, + (uint)((l >> 48) & 0xFFF) | 0x4000, // highest 4 bits indicate the uuid version + (uint)(h & 0x3FFF) | 0x8000, // the highest 2 bits indicate the UUID variant (10), + (long long)(rotl64(h, 50) & 0xFFFFFFFFFFFFull)); } /* Generates an RFC 9562 version 7 UUID into chunk @@ -6412,24 +6404,18 @@ void ha_generate_uuid_v4(struct buffer *output) */ void ha_generate_uuid_v7(struct buffer *output) { - uint32_t rnd[3]; - uint64_t last; + uint64_t l, h; uint64_t time; time = (date.tv_sec * 1000) + (date.tv_usec / 1000); - last = ha_random64(); - rnd[0] = last; - rnd[1] = last >> 32; - - last = ha_random64(); - rnd[2] = last; + ha_random64_pair_hashed(&l, &h); chunk_printf(output, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx", (uint)(time >> 16u), (uint)(time & 0xFFFF), - ((rnd[0] >> 16u) & 0xFFF) | 0x7000, // highest 4 bits indicate the uuid version - (rnd[1] & 0x3FFF) | 0x8000, // the highest 2 bits indicate the UUID variant (10), - (long long)((rnd[1] >> 14u) | ((uint64_t) rnd[2] << 18u)) & 0xFFFFFFFFFFFFull); + (uint)((l >> 16) & 0xFFF) | 0x7000, // highest 4 bits indicate the uuid version + (uint)(h & 0x3FFF) | 0x8000, // the highest 2 bits indicate the UUID variant (10), + (long long)(rotl64(h, 50) & 0xFFFFFFFFFFFFull)); }