mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-25 10:42:14 -04:00
BUG/MINOR: init: use more than ha_random64() for the cluster secret
When not set, the cluster secret is randomly generated by two consecutive calls to ha_random64(). However, the random64 PRNG may be partially observed on a fully idle machine (QUIC retry tokens, UUID, WS key), and it could be rolled back to the initial call that produced the secret. This is purely theoretical as a normally loaded system wouldn't reveal meaningful sequences, but better address this while it's still easy. The first here consists in isolating the cluster_secret from the PRNG sequence. When RAND_bytes() is available and works, it's used. Otherwise ha_random64() is mixed with uncorrelated bits from random(). This could be backported to stable releases.
This commit is contained in:
parent
c0e302fe79
commit
7d182a2ed5
1 changed files with 22 additions and 5 deletions
|
|
@ -1926,20 +1926,37 @@ static void dump_registered_keywords(void)
|
|||
|
||||
/* Generate a random cluster-secret in case the setting is not provided in the
|
||||
* configuration. This allows to use features which rely on it albeit with some
|
||||
* limitations.
|
||||
* limitations. The function doesn't (solely) use ha_random64() because this
|
||||
* secret is permanent, and ha_random64() can easily be leaked at various
|
||||
* places.
|
||||
*/
|
||||
static void generate_random_cluster_secret()
|
||||
{
|
||||
/* used as a default random cluster-secret if none defined. */
|
||||
uint64_t rand;
|
||||
union {
|
||||
uint64_t by64[2];
|
||||
uint32_t by32[4];
|
||||
uchar by8[16];
|
||||
} rand;
|
||||
|
||||
/* The caller must not overwrite an already defined secret. */
|
||||
BUG_ON(cluster_secret_isset);
|
||||
BUG_ON(sizeof(global.cluster_secret) != sizeof(rand));
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
if (RAND_bytes(rand.by8, sizeof(rand.by8)) != 1)
|
||||
#endif
|
||||
{
|
||||
/* no SSL or not working, fall back to other sources */
|
||||
rand.by64[0] = ha_random64();
|
||||
rand.by64[1] = ha_random64();
|
||||
rand.by32[0] ^= ((random() & 0x00ffff00) << 8) | ((random() & 0x00ffff00) >> 8);
|
||||
rand.by32[1] ^= ((random() & 0x00ffff00) << 8) | ((random() & 0x00ffff00) >> 8);
|
||||
rand.by32[2] ^= ((random() & 0x00ffff00) << 8) | ((random() & 0x00ffff00) >> 8);
|
||||
rand.by32[3] ^= ((random() & 0x00ffff00) << 8) | ((random() & 0x00ffff00) >> 8);
|
||||
}
|
||||
|
||||
rand = ha_random64();
|
||||
memcpy(global.cluster_secret, &rand, sizeof(rand));
|
||||
rand = ha_random64();
|
||||
memcpy(global.cluster_secret + sizeof(rand), &rand, sizeof(rand));
|
||||
cluster_secret_isset = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue