4545#include < sys/auxv.h>
4646#endif
4747
48- [[noreturn]] static void RandFailure ()
48+ namespace {
49+
50+ /* Number of random bytes returned by GetOSRand.
51+ * When changing this constant make sure to change all call sites, and make
52+ * sure that the underlying OS APIs for all platforms support the number.
53+ * (many cap out at 256 bytes).
54+ */
55+ static const int NUM_OS_RANDOM_BYTES = 32 ;
56+
57+
58+ [[noreturn]] void RandFailure ()
4959{
5060 LogPrintf (" Failed to read randomness, aborting\n " );
5161 std::abort ();
5262}
5363
54- static inline int64_t GetPerformanceCounter () noexcept
64+ inline int64_t GetPerformanceCounter () noexcept
5565{
5666 // Read the hardware time stamp counter when available.
5767 // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
@@ -72,18 +82,18 @@ static inline int64_t GetPerformanceCounter() noexcept
7282}
7383
7484#ifdef HAVE_GETCPUID
75- static bool g_rdrand_supported = false ;
76- static bool g_rdseed_supported = false ;
77- static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000 ;
78- static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000 ;
85+ bool g_rdrand_supported = false ;
86+ bool g_rdseed_supported = false ;
87+ constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000 ;
88+ constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000 ;
7989#ifdef bit_RDRND
8090static_assert (CPUID_F1_ECX_RDRAND == bit_RDRND, " Unexpected value for bit_RDRND" );
8191#endif
8292#ifdef bit_RDSEED
8393static_assert (CPUID_F7_EBX_RDSEED == bit_RDSEED, " Unexpected value for bit_RDSEED" );
8494#endif
8595
86- static void InitHardwareRand ()
96+ void InitHardwareRand ()
8797{
8898 uint32_t eax, ebx, ecx, edx;
8999 GetCPUID (1 , 0 , eax, ebx, ecx, edx);
@@ -96,7 +106,7 @@ static void InitHardwareRand()
96106 }
97107}
98108
99- static void ReportHardwareRand ()
109+ void ReportHardwareRand ()
100110{
101111 // This must be done in a separate function, as InitHardwareRand() may be indirectly called
102112 // from global constructors, before logging is initialized.
@@ -112,7 +122,7 @@ static void ReportHardwareRand()
112122 *
113123 * Must only be called when RdRand is supported.
114124 */
115- static uint64_t GetRdRand () noexcept
125+ uint64_t GetRdRand () noexcept
116126{
117127 // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
118128#ifdef __i386__
@@ -147,7 +157,7 @@ static uint64_t GetRdRand() noexcept
147157 *
148158 * Must only be called when RdSeed is supported.
149159 */
150- static uint64_t GetRdSeed () noexcept
160+ uint64_t GetRdSeed () noexcept
151161{
152162 // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
153163 // but pause after every failure.
@@ -181,16 +191,16 @@ static uint64_t GetRdSeed() noexcept
181191
182192#elif defined(__aarch64__) && defined(HWCAP2_RNG)
183193
184- static bool g_rndr_supported = false ;
194+ bool g_rndr_supported = false ;
185195
186- static void InitHardwareRand ()
196+ void InitHardwareRand ()
187197{
188198 if (getauxval (AT_HWCAP2) & HWCAP2_RNG) {
189199 g_rndr_supported = true ;
190200 }
191201}
192202
193- static void ReportHardwareRand ()
203+ void ReportHardwareRand ()
194204{
195205 // This must be done in a separate function, as InitHardwareRand() may be indirectly called
196206 // from global constructors, before logging is initialized.
@@ -203,7 +213,7 @@ static void ReportHardwareRand()
203213 *
204214 * Must only be called when RNDR is supported.
205215 */
206- static uint64_t GetRNDR () noexcept
216+ uint64_t GetRNDR () noexcept
207217{
208218 uint8_t ok;
209219 uint64_t r1;
@@ -221,7 +231,7 @@ static uint64_t GetRNDR() noexcept
221231 *
222232 * Must only be called when RNDRRS is supported.
223233 */
224- static uint64_t GetRNDRRS () noexcept
234+ uint64_t GetRNDRRS () noexcept
225235{
226236 uint8_t ok;
227237 uint64_t r1;
@@ -241,12 +251,12 @@ static uint64_t GetRNDRRS() noexcept
241251 * Slower sources should probably be invoked separately, and/or only from
242252 * RandAddPeriodic (which is called once a minute).
243253 */
244- static void InitHardwareRand () {}
245- static void ReportHardwareRand () {}
254+ void InitHardwareRand () {}
255+ void ReportHardwareRand () {}
246256#endif
247257
248258/* * Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
249- static void SeedHardwareFast (CSHA512& hasher) noexcept {
259+ void SeedHardwareFast (CSHA512& hasher) noexcept {
250260#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
251261 if (g_rdrand_supported) {
252262 uint64_t out = GetRdRand ();
@@ -263,7 +273,7 @@ static void SeedHardwareFast(CSHA512& hasher) noexcept {
263273}
264274
265275/* * Add 256 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
266- static void SeedHardwareSlow (CSHA512& hasher) noexcept {
276+ void SeedHardwareSlow (CSHA512& hasher) noexcept {
267277#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
268278 // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
269279 // guaranteed to produce independent randomness on every call.
@@ -296,7 +306,7 @@ static void SeedHardwareSlow(CSHA512& hasher) noexcept {
296306}
297307
298308/* * Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */
299- static void Strengthen (const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
309+ void Strengthen (const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
300310{
301311 CSHA512 inner_hasher;
302312 inner_hasher.Write (seed, sizeof (seed));
@@ -327,7 +337,7 @@ static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration du
327337/* * Fallback: get 32 bytes of system entropy from /dev/urandom. The most
328338 * compatible way to get cryptographic randomness on UNIX-ish platforms.
329339 */
330- [[maybe_unused]] static void GetDevURandom (unsigned char *ent32)
340+ [[maybe_unused]] void GetDevURandom (unsigned char *ent32)
331341{
332342 int f = open (" /dev/urandom" , O_RDONLY);
333343 if (f == -1 ) {
@@ -402,8 +412,6 @@ void GetOSRand(unsigned char *ent32)
402412#endif
403413}
404414
405- namespace {
406-
407415class RNGState {
408416 Mutex m_mutex;
409417 /* The RNG state consists of 256 bits of entropy, taken from the output of
@@ -521,20 +529,19 @@ RNGState& GetRNGState() noexcept
521529 static std::vector<RNGState, secure_allocator<RNGState>> g_rng (1 );
522530 return g_rng[0 ];
523531}
524- }
525532
526533/* A note on the use of noexcept in the seeding functions below:
527534 *
528535 * None of the RNG code should ever throw any exception.
529536 */
530537
531- static void SeedTimestamp (CSHA512& hasher) noexcept
538+ void SeedTimestamp (CSHA512& hasher) noexcept
532539{
533540 int64_t perfcounter = GetPerformanceCounter ();
534541 hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
535542}
536543
537- static void SeedFast (CSHA512& hasher) noexcept
544+ void SeedFast (CSHA512& hasher) noexcept
538545{
539546 unsigned char buffer[32 ];
540547
@@ -549,7 +556,7 @@ static void SeedFast(CSHA512& hasher) noexcept
549556 SeedTimestamp (hasher);
550557}
551558
552- static void SeedSlow (CSHA512& hasher, RNGState& rng) noexcept
559+ void SeedSlow (CSHA512& hasher, RNGState& rng) noexcept
553560{
554561 unsigned char buffer[32 ];
555562
@@ -571,7 +578,7 @@ static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
571578}
572579
573580/* * Extract entropy from rng, strengthen it, and feed it into hasher. */
574- static void SeedStrengthen (CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
581+ void SeedStrengthen (CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
575582{
576583 // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
577584 // Never use the deterministic PRNG for this, as the result is only used internally.
@@ -581,7 +588,7 @@ static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration
581588 Strengthen (strengthen_seed, dur, hasher);
582589}
583590
584- static void SeedPeriodic (CSHA512& hasher, RNGState& rng) noexcept
591+ void SeedPeriodic (CSHA512& hasher, RNGState& rng) noexcept
585592{
586593 // Everything that the 'fast' seeder includes
587594 SeedFast (hasher);
@@ -601,7 +608,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
601608 SeedStrengthen (hasher, rng, 10ms);
602609}
603610
604- static void SeedStartup (CSHA512& hasher, RNGState& rng) noexcept
611+ void SeedStartup (CSHA512& hasher, RNGState& rng) noexcept
605612{
606613 // Gather 256 bits of hardware randomness, if available
607614 SeedHardwareSlow (hasher);
@@ -627,7 +634,7 @@ enum class RNGLevel {
627634 PERIODIC, // !< Called by RandAddPeriodic()
628635};
629636
630- static void ProcRand (unsigned char * out, int num, RNGLevel level, bool always_use_real_rng) noexcept
637+ void ProcRand (unsigned char * out, int num, RNGLevel level, bool always_use_real_rng) noexcept
631638{
632639 // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
633640 RNGState& rng = GetRNGState ();
@@ -656,6 +663,9 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level, bool always_us
656663 }
657664}
658665
666+ } // namespace
667+
668+
659669/* * Internal function to set g_determinstic_rng. Only accessed from tests. */
660670void MakeRandDeterministicDANGEROUS (const uint256& seed) noexcept
661671{
@@ -679,13 +689,6 @@ void RandAddPeriodic() noexcept
679689
680690void RandAddEvent (const uint32_t event_info) noexcept { GetRNGState ().AddEvent (event_info); }
681691
682- uint256 GetRandHash () noexcept
683- {
684- uint256 hash;
685- GetRandBytes (hash);
686- return hash;
687- }
688-
689692void FastRandomContext::RandomSeed () noexcept
690693{
691694 uint256 seed = GetRandHash ();
0 commit comments