/* 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;
}