Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2021 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include <random.h>
7 :
8 : #include <compat/cpuid.h>
9 : #include <crypto/chacha20.h>
10 : #include <crypto/sha256.h>
11 : #include <crypto/sha512.h>
12 : #include <logging.h>
13 : #include <randomenv.h>
14 : #include <span.h>
15 : #include <support/allocators/secure.h>
16 : #include <support/cleanse.h>
17 : #include <sync.h>
18 : #include <util/time.h>
19 :
20 : #include <array>
21 : #include <cmath>
22 : #include <cstdlib>
23 : #include <thread>
24 :
25 : #ifdef WIN32
26 : #include <bcrypt.h>
27 : #else
28 : #include <fcntl.h>
29 : #endif
30 :
31 : #ifdef HAVE_SYS_GETRANDOM
32 : #include <sys/syscall.h>
33 : #include <linux/random.h>
34 : #endif
35 : #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
36 : #include <unistd.h>
37 : #include <sys/random.h>
38 : #endif
39 : #ifdef HAVE_SYSCTL_ARND
40 : #include <sys/sysctl.h>
41 : #endif
42 : #if defined(HAVE_STRONG_GETAUXVAL) && defined(__aarch64__)
43 : #include <sys/auxv.h>
44 : #endif
45 :
46 0 : [[noreturn]] static void RandFailure()
47 : {
48 0 : LogPrintf("Failed to read randomness, aborting\n");
49 0 : std::abort();
50 0 : }
51 :
52 5889097 : static inline int64_t GetPerformanceCounter() noexcept
53 : {
54 : // Read the hardware time stamp counter when available.
55 : // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
56 : #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
57 : return __rdtsc();
58 : #elif !defined(_MSC_VER) && defined(__i386__)
59 : uint64_t r = 0;
60 : __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
61 : return r;
62 : #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
63 : uint64_t r1 = 0, r2 = 0;
64 : __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
65 : return (r2 << 32) | r1;
66 : #else
67 : // Fall back to using standard library clock (usually microsecond or nanosecond precision)
68 5889097 : return std::chrono::high_resolution_clock::now().time_since_epoch().count();
69 : #endif
70 : }
71 :
72 : #ifdef HAVE_GETCPUID
73 : static bool g_rdrand_supported = false;
74 : static bool g_rdseed_supported = false;
75 : static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
76 : static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
77 : #ifdef bit_RDRND
78 : static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
79 : #endif
80 : #ifdef bit_RDSEED
81 : static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
82 : #endif
83 :
84 : static void InitHardwareRand()
85 : {
86 : uint32_t eax, ebx, ecx, edx;
87 : GetCPUID(1, 0, eax, ebx, ecx, edx);
88 : if (ecx & CPUID_F1_ECX_RDRAND) {
89 : g_rdrand_supported = true;
90 : }
91 : GetCPUID(7, 0, eax, ebx, ecx, edx);
92 : if (ebx & CPUID_F7_EBX_RDSEED) {
93 : g_rdseed_supported = true;
94 : }
95 : }
96 :
97 : static void ReportHardwareRand()
98 : {
99 : // This must be done in a separate function, as InitHardwareRand() may be indirectly called
100 : // from global constructors, before logging is initialized.
101 : if (g_rdseed_supported) {
102 : LogPrintf("Using RdSeed as an additional entropy source\n");
103 : }
104 : if (g_rdrand_supported) {
105 : LogPrintf("Using RdRand as an additional entropy source\n");
106 : }
107 : }
108 :
109 : /** Read 64 bits of entropy using rdrand.
110 : *
111 : * Must only be called when RdRand is supported.
112 : */
113 : static uint64_t GetRdRand() noexcept
114 : {
115 : // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
116 : #ifdef __i386__
117 : uint8_t ok;
118 : // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
119 : // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
120 : // but there is no way that the compiler could know that.
121 : uint32_t r1 = 0, r2 = 0;
122 : for (int i = 0; i < 10; ++i) {
123 : __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %eax
124 : if (ok) break;
125 : }
126 : for (int i = 0; i < 10; ++i) {
127 : __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdrand %eax
128 : if (ok) break;
129 : }
130 : return (((uint64_t)r2) << 32) | r1;
131 : #elif defined(__x86_64__) || defined(__amd64__)
132 : uint8_t ok;
133 : uint64_t r1 = 0; // See above why we initialize to 0.
134 : for (int i = 0; i < 10; ++i) {
135 : __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %rax
136 : if (ok) break;
137 : }
138 : return r1;
139 : #else
140 : #error "RdRand is only supported on x86 and x86_64"
141 : #endif
142 : }
143 :
144 : /** Read 64 bits of entropy using rdseed.
145 : *
146 : * Must only be called when RdSeed is supported.
147 : */
148 : static uint64_t GetRdSeed() noexcept
149 : {
150 : // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
151 : // but pause after every failure.
152 : #ifdef __i386__
153 : uint8_t ok;
154 : uint32_t r1, r2;
155 : do {
156 : __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %eax
157 : if (ok) break;
158 : __asm__ volatile ("pause");
159 : } while(true);
160 : do {
161 : __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdseed %eax
162 : if (ok) break;
163 : __asm__ volatile ("pause");
164 : } while(true);
165 : return (((uint64_t)r2) << 32) | r1;
166 : #elif defined(__x86_64__) || defined(__amd64__)
167 : uint8_t ok;
168 : uint64_t r1;
169 : do {
170 : __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %rax
171 : if (ok) break;
172 : __asm__ volatile ("pause");
173 : } while(true);
174 : return r1;
175 : #else
176 : #error "RdSeed is only supported on x86 and x86_64"
177 : #endif
178 : }
179 :
180 : #elif defined(__aarch64__) && defined(HWCAP2_RNG)
181 :
182 : static bool g_rndr_supported = false;
183 :
184 : static void InitHardwareRand()
185 : {
186 : if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
187 : g_rndr_supported = true;
188 : }
189 : }
190 :
191 : static void ReportHardwareRand()
192 : {
193 : // This must be done in a separate function, as InitHardwareRand() may be indirectly called
194 : // from global constructors, before logging is initialized.
195 : if (g_rndr_supported) {
196 : LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n");
197 : }
198 : }
199 :
200 : /** Read 64 bits of entropy using rndr.
201 : *
202 : * Must only be called when RNDR is supported.
203 : */
204 : static uint64_t GetRNDR() noexcept
205 : {
206 : uint8_t ok;
207 : uint64_t r1;
208 : do {
209 : // https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDR--Random-Number
210 : __asm__ volatile("mrs %0, s3_3_c2_c4_0; cset %w1, ne;"
211 : : "=r"(r1), "=r"(ok)::"cc");
212 : if (ok) break;
213 : __asm__ volatile("yield");
214 : } while (true);
215 : return r1;
216 : }
217 :
218 : /** Read 64 bits of entropy using rndrrs.
219 : *
220 : * Must only be called when RNDRRS is supported.
221 : */
222 : static uint64_t GetRNDRRS() noexcept
223 : {
224 : uint8_t ok;
225 : uint64_t r1;
226 : do {
227 : // https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDRRS--Reseeded-Random-Number
228 : __asm__ volatile("mrs %0, s3_3_c2_c4_1; cset %w1, ne;"
229 : : "=r"(r1), "=r"(ok)::"cc");
230 : if (ok) break;
231 : __asm__ volatile("yield");
232 : } while (true);
233 : return r1;
234 : }
235 :
236 : #else
237 : /* Access to other hardware random number generators could be added here later,
238 : * assuming it is sufficiently fast (in the order of a few hundred CPU cycles).
239 : * Slower sources should probably be invoked separately, and/or only from
240 : * RandAddPeriodic (which is called once a minute).
241 : */
242 3461 : static void InitHardwareRand() {}
243 3168 : static void ReportHardwareRand() {}
244 : #endif
245 :
246 : /** Add 64 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
247 4646692 : static void SeedHardwareFast(CSHA512& hasher) noexcept {
248 : #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
249 : if (g_rdrand_supported) {
250 : uint64_t out = GetRdRand();
251 : hasher.Write((const unsigned char*)&out, sizeof(out));
252 : return;
253 : }
254 : #elif defined(__aarch64__) && defined(HWCAP2_RNG)
255 : if (g_rndr_supported) {
256 : uint64_t out = GetRNDR();
257 : hasher.Write((const unsigned char*)&out, sizeof(out));
258 : return;
259 : }
260 : #endif
261 4646692 : }
262 :
263 : /** Add 256 bits of entropy gathered from hardware to hasher. Do nothing if not supported. */
264 3461 : static void SeedHardwareSlow(CSHA512& hasher) noexcept {
265 : #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
266 : // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
267 : // guaranteed to produce independent randomness on every call.
268 : if (g_rdseed_supported) {
269 : for (int i = 0; i < 4; ++i) {
270 : uint64_t out = GetRdSeed();
271 : hasher.Write((const unsigned char*)&out, sizeof(out));
272 : }
273 : return;
274 : }
275 : // When falling back to RdRand, XOR the result of 1024 results.
276 : // This guarantees a reseeding occurs between each.
277 : if (g_rdrand_supported) {
278 : for (int i = 0; i < 4; ++i) {
279 : uint64_t out = 0;
280 : for (int j = 0; j < 1024; ++j) out ^= GetRdRand();
281 : hasher.Write((const unsigned char*)&out, sizeof(out));
282 : }
283 : return;
284 : }
285 : #elif defined(__aarch64__) && defined(HWCAP2_RNG)
286 : if (g_rndr_supported) {
287 : for (int i = 0; i < 4; ++i) {
288 : uint64_t out = GetRNDRRS();
289 : hasher.Write((const unsigned char*)&out, sizeof(out));
290 : }
291 : return;
292 : }
293 : #endif
294 3461 : }
295 :
296 : /** Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher. */
297 8844 : static void Strengthen(const unsigned char (&seed)[32], SteadyClock::duration dur, CSHA512& hasher) noexcept
298 : {
299 8844 : CSHA512 inner_hasher;
300 8844 : inner_hasher.Write(seed, sizeof(seed));
301 :
302 : // Hash loop
303 : unsigned char buffer[64];
304 8844 : const auto stop{SteadyClock::now() + dur};
305 8844 : do {
306 258727469 : for (int i = 0; i < 1000; ++i) {
307 258469000 : inner_hasher.Finalize(buffer);
308 258469000 : inner_hasher.Reset();
309 258469000 : inner_hasher.Write(buffer, sizeof(buffer));
310 258469000 : }
311 : // Benchmark operation and feed it into outer hasher.
312 258469 : int64_t perf = GetPerformanceCounter();
313 258469 : hasher.Write((const unsigned char*)&perf, sizeof(perf));
314 258469 : } while (SteadyClock::now() < stop);
315 :
316 : // Produce output from inner state and feed it to outer hasher.
317 8844 : inner_hasher.Finalize(buffer);
318 8844 : hasher.Write(buffer, sizeof(buffer));
319 : // Try to clean up.
320 8844 : inner_hasher.Reset();
321 8844 : memory_cleanse(buffer, sizeof(buffer));
322 8844 : }
323 :
324 : #ifndef WIN32
325 : /** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
326 : * compatible way to get cryptographic randomness on UNIX-ish platforms.
327 : */
328 0 : static void GetDevURandom(unsigned char *ent32)
329 : {
330 0 : int f = open("/dev/urandom", O_RDONLY);
331 0 : if (f == -1) {
332 0 : RandFailure();
333 : }
334 0 : int have = 0;
335 0 : do {
336 0 : ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
337 0 : if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
338 0 : close(f);
339 0 : RandFailure();
340 : }
341 0 : have += n;
342 0 : } while (have < NUM_OS_RANDOM_BYTES);
343 0 : close(f);
344 0 : }
345 : #endif
346 :
347 : /** Get 32 bytes of system entropy. */
348 94745 : void GetOSRand(unsigned char *ent32)
349 : {
350 : #if defined(WIN32)
351 : constexpr uint32_t STATUS_SUCCESS{0x00000000};
352 : NTSTATUS status = BCryptGenRandom(/*hAlgorithm=*/NULL,
353 : /*pbBuffer=*/ent32,
354 : /*cbBuffer=*/NUM_OS_RANDOM_BYTES,
355 : /*dwFlags=*/BCRYPT_USE_SYSTEM_PREFERRED_RNG);
356 :
357 : if (status != STATUS_SUCCESS) {
358 : RandFailure();
359 : }
360 : #elif defined(HAVE_SYS_GETRANDOM)
361 : /* Linux. From the getrandom(2) man page:
362 : * "If the urandom source has been initialized, reads of up to 256 bytes
363 : * will always return as many bytes as requested and will not be
364 : * interrupted by signals."
365 : */
366 : int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
367 : if (rv != NUM_OS_RANDOM_BYTES) {
368 : if (rv < 0 && errno == ENOSYS) {
369 : /* Fallback for kernel <3.17: the return value will be -1 and errno
370 : * ENOSYS if the syscall is not available, in that case fall back
371 : * to /dev/urandom.
372 : */
373 : GetDevURandom(ent32);
374 : } else {
375 : RandFailure();
376 : }
377 : }
378 : #elif defined(__OpenBSD__)
379 : /* OpenBSD. From the arc4random(3) man page:
380 : "Use of these functions is encouraged for almost all random number
381 : consumption because the other interfaces are deficient in either
382 : quality, portability, standardization, or availability."
383 : The function call is always successful.
384 : */
385 : arc4random_buf(ent32, NUM_OS_RANDOM_BYTES);
386 : // Silence a compiler warning about unused function.
387 : (void)GetDevURandom;
388 : #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
389 : /* getentropy() is available on macOS 10.12 and later.
390 : */
391 94745 : if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
392 0 : RandFailure();
393 : }
394 : // Silence a compiler warning about unused function.
395 : (void)GetDevURandom;
396 : #elif defined(HAVE_SYSCTL_ARND)
397 : /* FreeBSD, NetBSD and similar. It is possible for the call to return less
398 : * bytes than requested, so need to read in a loop.
399 : */
400 : static int name[2] = {CTL_KERN, KERN_ARND};
401 : int have = 0;
402 : do {
403 : size_t len = NUM_OS_RANDOM_BYTES - have;
404 : if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) != 0) {
405 : RandFailure();
406 : }
407 : have += len;
408 : } while (have < NUM_OS_RANDOM_BYTES);
409 : // Silence a compiler warning about unused function.
410 : (void)GetDevURandom;
411 : #else
412 : /* Fall back to /dev/urandom if there is no specific method implemented to
413 : * get system entropy for this OS.
414 : */
415 : GetDevURandom(ent32);
416 : #endif
417 94745 : }
418 :
419 : namespace {
420 :
421 : class RNGState {
422 : Mutex m_mutex;
423 : /* The RNG state consists of 256 bits of entropy, taken from the output of
424 : * one operation's SHA512 output, and fed as input to the next one.
425 : * Carrying 256 bits of entropy should be sufficient to guarantee
426 : * unpredictability as long as any entropy source was ever unpredictable
427 : * to an attacker. To protect against situations where an attacker might
428 : * observe the RNG's state, fresh entropy is always mixed when
429 : * GetStrongRandBytes is called.
430 : */
431 3461 : unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
432 3461 : uint64_t m_counter GUARDED_BY(m_mutex) = 0;
433 3461 : bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
434 :
435 : Mutex m_events_mutex;
436 : CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
437 :
438 : public:
439 10383 : RNGState() noexcept
440 3461 : {
441 3461 : InitHardwareRand();
442 6922 : }
443 :
444 34 : ~RNGState() = default;
445 :
446 881199 : void AddEvent(uint32_t event_info) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
447 : {
448 881199 : LOCK(m_events_mutex);
449 :
450 881199 : m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
451 : // Get the low four bytes of the performance counter. This translates to roughly the
452 : // subsecond part.
453 881199 : uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
454 881199 : m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
455 881199 : }
456 :
457 : /**
458 : * Feed (the hash of) all events added through AddEvent() to hasher.
459 : */
460 96762 : void SeedEvents(CSHA512& hasher) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_events_mutex)
461 : {
462 : // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
463 : // since we want it to be fast as network peers may be able to trigger it repeatedly.
464 96762 : LOCK(m_events_mutex);
465 :
466 : unsigned char events_hash[32];
467 96762 : m_events_hasher.Finalize(events_hash);
468 96762 : hasher.Write(events_hash, 32);
469 :
470 : // Re-initialize the hasher with the finalized state to use later.
471 96762 : m_events_hasher.Reset();
472 96762 : m_events_hasher.Write(events_hash, 32);
473 96762 : }
474 :
475 : /** Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.
476 : *
477 : * If this function has never been called with strong_seed = true, false is returned.
478 : */
479 4658564 : bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
480 : {
481 4658594 : assert(num <= 32);
482 : unsigned char buf[64];
483 : static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
484 : bool ret;
485 : {
486 4658564 : LOCK(m_mutex);
487 4658579 : ret = (m_strongly_seeded |= strong_seed);
488 : // Write the current state of the RNG into the hasher
489 4658579 : hasher.Write(m_state, 32);
490 : // Write a new counter number into the state
491 4658579 : hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
492 4658579 : ++m_counter;
493 : // Finalize the hasher
494 4658579 : hasher.Finalize(buf);
495 : // Store the last 32 bytes of the hash output as new RNG state.
496 4658579 : memcpy(m_state, buf + 32, 32);
497 4658579 : }
498 : // If desired, copy (up to) the first 32 bytes of the hash output as output.
499 4658579 : if (num) {
500 4646995 : assert(out != nullptr);
501 4646995 : memcpy(out, buf, num);
502 4646995 : }
503 : // Best effort cleanup of internal state
504 4658579 : hasher.Reset();
505 4658579 : memory_cleanse(buf, 64);
506 4658564 : return ret;
507 : }
508 : };
509 :
510 5527398 : RNGState& GetRNGState() noexcept
511 : {
512 : // This idiom relies on the guarantee that static variable are initialized
513 : // on first call, even when multiple parallel calls are permitted.
514 5527398 : static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
515 5527398 : return g_rng[0];
516 : }
517 : }
518 :
519 : /* A note on the use of noexcept in the seeding functions below:
520 : *
521 : * None of the RNG code should ever throw any exception.
522 : */
523 :
524 4743452 : static void SeedTimestamp(CSHA512& hasher) noexcept
525 : {
526 4743452 : int64_t perfcounter = GetPerformanceCounter();
527 4743452 : hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
528 4743452 : }
529 :
530 4646687 : static void SeedFast(CSHA512& hasher) noexcept
531 : {
532 : unsigned char buffer[32];
533 :
534 : // Stack pointer to indirectly commit to thread/callstack
535 4646687 : const unsigned char* ptr = buffer;
536 4646687 : hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
537 :
538 : // Hardware randomness is very fast when available; use it always.
539 4646687 : SeedHardwareFast(hasher);
540 :
541 : // High-precision timestamp
542 4646687 : SeedTimestamp(hasher);
543 4646687 : }
544 :
545 91378 : static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
546 : {
547 : unsigned char buffer[32];
548 :
549 : // Everything that the 'fast' seeder includes
550 91378 : SeedFast(hasher);
551 :
552 : // OS randomness
553 91379 : GetOSRand(buffer);
554 91379 : hasher.Write(buffer, sizeof(buffer));
555 :
556 : // Add the events hasher into the mix
557 91378 : rng.SeedEvents(hasher);
558 :
559 : // High-precision timestamp.
560 : //
561 : // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
562 : // benchmark of all the entropy gathering sources in this function).
563 91378 : SeedTimestamp(hasher);
564 91378 : }
565 :
566 : /** Extract entropy from rng, strengthen it, and feed it into hasher. */
567 8844 : static void SeedStrengthen(CSHA512& hasher, RNGState& rng, SteadyClock::duration dur) noexcept
568 : {
569 : // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
570 : unsigned char strengthen_seed[32];
571 8844 : rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
572 : // Strengthen the seed, and feed it into hasher.
573 8844 : Strengthen(strengthen_seed, dur, hasher);
574 8844 : }
575 :
576 5383 : static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
577 : {
578 : // Everything that the 'fast' seeder includes
579 5383 : SeedFast(hasher);
580 :
581 : // High-precision timestamp
582 5383 : SeedTimestamp(hasher);
583 :
584 : // Add the events hasher into the mix
585 5383 : rng.SeedEvents(hasher);
586 :
587 : // Dynamic environment data (performance monitoring, ...)
588 5383 : auto old_size = hasher.Size();
589 5383 : RandAddDynamicEnv(hasher);
590 5383 : LogPrint(BCLog::RANDOM, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
591 :
592 : // Strengthen for 10 ms
593 5383 : SeedStrengthen(hasher, rng, 10ms);
594 5383 : }
595 :
596 3461 : static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
597 : {
598 : // Gather 256 bits of hardware randomness, if available
599 3461 : SeedHardwareSlow(hasher);
600 :
601 : // Everything that the 'slow' seeder includes.
602 3461 : SeedSlow(hasher, rng);
603 :
604 : // Dynamic environment data (performance monitoring, ...)
605 3461 : auto old_size = hasher.Size();
606 3461 : RandAddDynamicEnv(hasher);
607 :
608 : // Static environment data
609 3461 : RandAddStaticEnv(hasher);
610 3461 : LogPrint(BCLog::RANDOM, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
611 :
612 : // Strengthen for 100 ms
613 3461 : SeedStrengthen(hasher, rng, 100ms);
614 3461 : }
615 :
616 : enum class RNGLevel {
617 : FAST, //!< Automatically called by GetRandBytes
618 : SLOW, //!< Automatically called by GetStrongRandBytes
619 : PERIODIC, //!< Called by RandAddPeriodic()
620 : };
621 :
622 4643217 : static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
623 : {
624 : // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
625 4643217 : RNGState& rng = GetRNGState();
626 :
627 4643217 : assert(num <= 32);
628 :
629 4643217 : CSHA512 hasher;
630 4643217 : switch (level) {
631 : case RNGLevel::FAST:
632 4549918 : SeedFast(hasher);
633 4549918 : break;
634 : case RNGLevel::SLOW:
635 87916 : SeedSlow(hasher, rng);
636 87916 : break;
637 : case RNGLevel::PERIODIC:
638 5383 : SeedPeriodic(hasher, rng);
639 5383 : break;
640 : }
641 :
642 : // Combine with and update state
643 4643217 : if (!rng.MixExtract(out, num, std::move(hasher), false)) {
644 : // On the first invocation, also seed with SeedStartup().
645 3461 : CSHA512 startup_hasher;
646 3461 : SeedStartup(startup_hasher, rng);
647 3461 : rng.MixExtract(out, num, std::move(startup_hasher), true);
648 3461 : }
649 4643217 : }
650 :
651 4546758 : void GetRandBytes(Span<unsigned char> bytes) noexcept { ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST); }
652 87917 : void GetStrongRandBytes(Span<unsigned char> bytes) noexcept { ProcRand(bytes.data(), bytes.size(), RNGLevel::SLOW); }
653 5383 : void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
654 881199 : void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
655 :
656 : bool g_mock_deterministic_tests{false};
657 :
658 4032244 : uint64_t GetRandInternal(uint64_t nMax) noexcept
659 : {
660 4032244 : return FastRandomContext(g_mock_deterministic_tests).randrange(nMax);
661 : }
662 :
663 4474118 : uint256 GetRandHash() noexcept
664 : {
665 4474123 : uint256 hash;
666 4474113 : GetRandBytes(hash);
667 4474108 : return hash;
668 : }
669 :
670 8560 : bool GetRandBool(double rate)
671 : {
672 8560 : if (rate == 0.0) {
673 8532 : return false;
674 : }
675 :
676 28 : const uint64_t v = 100000000;
677 28 : uint64_t r = GetRand(v + 1);
678 28 : return r <= v * rate;
679 8560 : }
680 :
681 4464871 : void FastRandomContext::RandomSeed()
682 : {
683 4464871 : uint256 seed = GetRandHash();
684 4464871 : rng.SetKey(MakeByteSpan(seed));
685 4464871 : requires_seed = false;
686 4464871 : }
687 :
688 395647 : uint256 FastRandomContext::rand256() noexcept
689 : {
690 395647 : if (requires_seed) RandomSeed();
691 395647 : uint256 ret;
692 395647 : rng.Keystream(MakeWritableByteSpan(ret));
693 395647 : return ret;
694 : }
695 :
696 : template <typename B>
697 56155 : std::vector<B> FastRandomContext::randbytes(size_t len)
698 : {
699 56155 : std::vector<B> ret(len);
700 56155 : fillrand(MakeWritableByteSpan(ret));
701 56155 : return ret;
702 56155 : }
703 : template std::vector<unsigned char> FastRandomContext::randbytes(size_t);
704 : template std::vector<std::byte> FastRandomContext::randbytes(size_t);
705 :
706 56534 : void FastRandomContext::fillrand(Span<std::byte> output)
707 : {
708 56534 : if (requires_seed) RandomSeed();
709 56534 : rng.Keystream(output);
710 56534 : }
711 :
712 1512 : FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)), bitbuf_size(0) {}
713 :
714 3033 : bool Random_SanityCheck()
715 : {
716 3033 : uint64_t start = GetPerformanceCounter();
717 :
718 : /* This does not measure the quality of randomness, but it does test that
719 : * GetOSRand() overwrites all 32 bytes of the output given a maximum
720 : * number of tries.
721 : */
722 : static constexpr int MAX_TRIES{1024};
723 : uint8_t data[NUM_OS_RANDOM_BYTES];
724 3033 : bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
725 : int num_overwritten;
726 3033 : int tries = 0;
727 : /* Loop until all bytes have been overwritten at least once, or max number tries reached */
728 3033 : do {
729 3367 : memset(data, 0, NUM_OS_RANDOM_BYTES);
730 3367 : GetOSRand(data);
731 111111 : for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
732 107744 : overwritten[x] |= (data[x] != 0);
733 107744 : }
734 :
735 3367 : num_overwritten = 0;
736 111111 : for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
737 107744 : if (overwritten[x]) {
738 107383 : num_overwritten += 1;
739 107383 : }
740 107744 : }
741 :
742 3367 : tries += 1;
743 3367 : } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
744 3033 : if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
745 :
746 : // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
747 3033 : std::this_thread::sleep_for(std::chrono::milliseconds(1));
748 3033 : uint64_t stop = GetPerformanceCounter();
749 3033 : if (stop == start) return false;
750 :
751 : // We called GetPerformanceCounter. Use it as entropy.
752 3033 : CSHA512 to_add;
753 3033 : to_add.Write((const unsigned char*)&start, sizeof(start));
754 3033 : to_add.Write((const unsigned char*)&stop, sizeof(stop));
755 3033 : GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
756 :
757 3033 : return true;
758 3033 : }
759 :
760 : static constexpr std::array<std::byte, ChaCha20::KEYLEN> ZERO_KEY{};
761 :
762 10291746 : FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), rng(ZERO_KEY), bitbuf_size(0)
763 5145875 : {
764 : // Note that despite always initializing with ZERO_KEY, requires_seed is set to true if not
765 : // fDeterministic. That means the rng will be reinitialized with a secure random key upon first
766 : // use.
767 10291746 : }
768 :
769 770 : FastRandomContext& FastRandomContext::operator=(FastRandomContext&& from) noexcept
770 : {
771 770 : requires_seed = from.requires_seed;
772 770 : rng = from.rng;
773 770 : bitbuf = from.bitbuf;
774 770 : bitbuf_size = from.bitbuf_size;
775 770 : from.requires_seed = true;
776 770 : from.bitbuf_size = 0;
777 770 : return *this;
778 : }
779 :
780 3168 : void RandomInit()
781 : {
782 : // Invoke RNG code to trigger initialization (if not already performed)
783 3168 : ProcRand(nullptr, 0, RNGLevel::FAST);
784 :
785 3168 : ReportHardwareRand();
786 3168 : }
787 :
788 99003 : std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
789 : {
790 99003 : double unscaled = -std::log1p(GetRand(uint64_t{1} << 48) * -0.0000000000000035527136788 /* -1/2^48 */);
791 99003 : return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
792 : }
|