Bitcoin Core  22.99.0
P2P Digital Currency
random.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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/sha256.h>
10 #include <crypto/sha512.h>
11 #include <support/cleanse.h>
12 #ifdef WIN32
13 #include <compat.h> // for Windows API
14 #include <wincrypt.h>
15 #endif
16 #include <logging.h> // for LogPrintf()
17 #include <randomenv.h>
19 #include <sync.h> // for Mutex
20 #include <util/time.h> // for GetTimeMicros()
21 
22 #include <stdlib.h>
23 #include <thread>
24 
25 #ifndef WIN32
26 #include <fcntl.h>
27 #include <sys/time.h>
28 #endif
29 
30 #ifdef HAVE_SYS_GETRANDOM
31 #include <sys/syscall.h>
32 #include <linux/random.h>
33 #endif
34 #if defined(HAVE_GETENTROPY) || (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
35 #include <unistd.h>
36 #endif
37 #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
38 #include <sys/random.h>
39 #endif
40 #ifdef HAVE_SYSCTL_ARND
41 #include <sys/sysctl.h>
42 #endif
43 
44 [[noreturn]] static void RandFailure()
45 {
46  LogPrintf("Failed to read randomness, aborting\n");
47  std::abort();
48 }
49 
50 static inline int64_t GetPerformanceCounter() noexcept
51 {
52  // Read the hardware time stamp counter when available.
53  // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
54 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
55  return __rdtsc();
56 #elif !defined(_MSC_VER) && defined(__i386__)
57  uint64_t r = 0;
58  __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
59  return r;
60 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
61  uint64_t r1 = 0, r2 = 0;
62  __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
63  return (r2 << 32) | r1;
64 #else
65  // Fall back to using C++11 clock (usually microsecond or nanosecond precision)
66  return std::chrono::high_resolution_clock::now().time_since_epoch().count();
67 #endif
68 }
69 
70 #ifdef HAVE_GETCPUID
71 static bool g_rdrand_supported = false;
72 static bool g_rdseed_supported = false;
73 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
74 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
75 #ifdef bit_RDRND
76 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
77 #endif
78 #ifdef bit_RDSEED
79 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
80 #endif
81 
82 static void InitHardwareRand()
83 {
84  uint32_t eax, ebx, ecx, edx;
85  GetCPUID(1, 0, eax, ebx, ecx, edx);
86  if (ecx & CPUID_F1_ECX_RDRAND) {
87  g_rdrand_supported = true;
88  }
89  GetCPUID(7, 0, eax, ebx, ecx, edx);
90  if (ebx & CPUID_F7_EBX_RDSEED) {
91  g_rdseed_supported = true;
92  }
93 }
94 
95 static void ReportHardwareRand()
96 {
97  // This must be done in a separate function, as InitHardwareRand() may be indirectly called
98  // from global constructors, before logging is initialized.
99  if (g_rdseed_supported) {
100  LogPrintf("Using RdSeed as additional entropy source\n");
101  }
102  if (g_rdrand_supported) {
103  LogPrintf("Using RdRand as an additional entropy source\n");
104  }
105 }
106 
111 static uint64_t GetRdRand() noexcept
112 {
113  // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
114 #ifdef __i386__
115  uint8_t ok;
116  // Initialize to 0 to silence a compiler warning that r1 or r2 may be used
117  // uninitialized. Even if rdrand fails (!ok) it will set the output to 0,
118  // but there is no way that the compiler could know that.
119  uint32_t r1 = 0, r2 = 0;
120  for (int i = 0; i < 10; ++i) {
121  __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %eax
122  if (ok) break;
123  }
124  for (int i = 0; i < 10; ++i) {
125  __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdrand %eax
126  if (ok) break;
127  }
128  return (((uint64_t)r2) << 32) | r1;
129 #elif defined(__x86_64__) || defined(__amd64__)
130  uint8_t ok;
131  uint64_t r1 = 0; // See above why we initialize to 0.
132  for (int i = 0; i < 10; ++i) {
133  __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %rax
134  if (ok) break;
135  }
136  return r1;
137 #else
138 #error "RdRand is only supported on x86 and x86_64"
139 #endif
140 }
141 
146 static uint64_t GetRdSeed() noexcept
147 {
148  // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
149  // but pause after every failure.
150 #ifdef __i386__
151  uint8_t ok;
152  uint32_t r1, r2;
153  do {
154  __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %eax
155  if (ok) break;
156  __asm__ volatile ("pause");
157  } while(true);
158  do {
159  __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdseed %eax
160  if (ok) break;
161  __asm__ volatile ("pause");
162  } while(true);
163  return (((uint64_t)r2) << 32) | r1;
164 #elif defined(__x86_64__) || defined(__amd64__)
165  uint8_t ok;
166  uint64_t r1;
167  do {
168  __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %rax
169  if (ok) break;
170  __asm__ volatile ("pause");
171  } while(true);
172  return r1;
173 #else
174 #error "RdSeed is only supported on x86 and x86_64"
175 #endif
176 }
177 
178 #else
179 /* Access to other hardware random number generators could be added here later,
180  * assuming it is sufficiently fast (in the order of a few hundred CPU cycles).
181  * Slower sources should probably be invoked separately, and/or only from
182  * RandAddPeriodic (which is called once a minute).
183  */
184 static void InitHardwareRand() {}
185 static void ReportHardwareRand() {}
186 #endif
187 
189 static void SeedHardwareFast(CSHA512& hasher) noexcept {
190 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
191  if (g_rdrand_supported) {
192  uint64_t out = GetRdRand();
193  hasher.Write((const unsigned char*)&out, sizeof(out));
194  return;
195  }
196 #endif
197 }
198 
200 static void SeedHardwareSlow(CSHA512& hasher) noexcept {
201 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
202  // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
203  // guaranteed to produce independent randomness on every call.
204  if (g_rdseed_supported) {
205  for (int i = 0; i < 4; ++i) {
206  uint64_t out = GetRdSeed();
207  hasher.Write((const unsigned char*)&out, sizeof(out));
208  }
209  return;
210  }
211  // When falling back to RdRand, XOR the result of 1024 results.
212  // This guarantees a reseeding occurs between each.
213  if (g_rdrand_supported) {
214  for (int i = 0; i < 4; ++i) {
215  uint64_t out = 0;
216  for (int j = 0; j < 1024; ++j) out ^= GetRdRand();
217  hasher.Write((const unsigned char*)&out, sizeof(out));
218  }
219  return;
220  }
221 #endif
222 }
223 
225 static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA512& hasher) noexcept
226 {
227  CSHA512 inner_hasher;
228  inner_hasher.Write(seed, sizeof(seed));
229 
230  // Hash loop
231  unsigned char buffer[64];
232  int64_t stop = GetTimeMicros() + microseconds;
233  do {
234  for (int i = 0; i < 1000; ++i) {
235  inner_hasher.Finalize(buffer);
236  inner_hasher.Reset();
237  inner_hasher.Write(buffer, sizeof(buffer));
238  }
239  // Benchmark operation and feed it into outer hasher.
240  int64_t perf = GetPerformanceCounter();
241  hasher.Write((const unsigned char*)&perf, sizeof(perf));
242  } while (GetTimeMicros() < stop);
243 
244  // Produce output from inner state and feed it to outer hasher.
245  inner_hasher.Finalize(buffer);
246  hasher.Write(buffer, sizeof(buffer));
247  // Try to clean up.
248  inner_hasher.Reset();
249  memory_cleanse(buffer, sizeof(buffer));
250 }
251 
252 #ifndef WIN32
253 
256 static void GetDevURandom(unsigned char *ent32)
257 {
258  int f = open("/dev/urandom", O_RDONLY);
259  if (f == -1) {
260  RandFailure();
261  }
262  int have = 0;
263  do {
264  ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
265  if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
266  close(f);
267  RandFailure();
268  }
269  have += n;
270  } while (have < NUM_OS_RANDOM_BYTES);
271  close(f);
272 }
273 #endif
274 
276 void GetOSRand(unsigned char *ent32)
277 {
278 #if defined(WIN32)
279  HCRYPTPROV hProvider;
280  int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
281  if (!ret) {
282  RandFailure();
283  }
284  ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
285  if (!ret) {
286  RandFailure();
287  }
288  CryptReleaseContext(hProvider, 0);
289 #elif defined(HAVE_SYS_GETRANDOM)
290  /* Linux. From the getrandom(2) man page:
291  * "If the urandom source has been initialized, reads of up to 256 bytes
292  * will always return as many bytes as requested and will not be
293  * interrupted by signals."
294  */
295  int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
296  if (rv != NUM_OS_RANDOM_BYTES) {
297  if (rv < 0 && errno == ENOSYS) {
298  /* Fallback for kernel <3.17: the return value will be -1 and errno
299  * ENOSYS if the syscall is not available, in that case fall back
300  * to /dev/urandom.
301  */
302  GetDevURandom(ent32);
303  } else {
304  RandFailure();
305  }
306  }
307 #elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
308  /* On OpenBSD this can return up to 256 bytes of entropy, will return an
309  * error if more are requested.
310  * The call cannot return less than the requested number of bytes.
311  getentropy is explicitly limited to openbsd here, as a similar (but not
312  the same) function may exist on other platforms via glibc.
313  */
314  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
315  RandFailure();
316  }
317  // Silence a compiler warning about unused function.
318  (void)GetDevURandom;
319 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
320  /* getentropy() is available on macOS 10.12 and later.
321  */
322  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
323  RandFailure();
324  }
325  // Silence a compiler warning about unused function.
326  (void)GetDevURandom;
327 #elif defined(HAVE_SYSCTL_ARND)
328  /* FreeBSD, NetBSD and similar. It is possible for the call to return less
329  * bytes than requested, so need to read in a loop.
330  */
331  static int name[2] = {CTL_KERN, KERN_ARND};
332  int have = 0;
333  do {
334  size_t len = NUM_OS_RANDOM_BYTES - have;
335  if (sysctl(name, std::size(name), ent32 + have, &len, nullptr, 0) != 0) {
336  RandFailure();
337  }
338  have += len;
339  } while (have < NUM_OS_RANDOM_BYTES);
340  // Silence a compiler warning about unused function.
341  (void)GetDevURandom;
342 #else
343  /* Fall back to /dev/urandom if there is no specific method implemented to
344  * get system entropy for this OS.
345  */
346  GetDevURandom(ent32);
347 #endif
348 }
349 
350 namespace {
351 
352 class RNGState {
353  Mutex m_mutex;
354  /* The RNG state consists of 256 bits of entropy, taken from the output of
355  * one operation's SHA512 output, and fed as input to the next one.
356  * Carrying 256 bits of entropy should be sufficient to guarantee
357  * unpredictability as long as any entropy source was ever unpredictable
358  * to an attacker. To protect against situations where an attacker might
359  * observe the RNG's state, fresh entropy is always mixed when
360  * GetStrongRandBytes is called.
361  */
362  unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
363  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
364  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
365 
366  Mutex m_events_mutex;
367  CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
368 
369 public:
370  RNGState() noexcept
371  {
373  }
374 
375  ~RNGState()
376  {
377  }
378 
379  void AddEvent(uint32_t event_info) noexcept
380  {
381  LOCK(m_events_mutex);
382 
383  m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
384  // Get the low four bytes of the performance counter. This translates to roughly the
385  // subsecond part.
386  uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
387  m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
388  }
389 
393  void SeedEvents(CSHA512& hasher) noexcept
394  {
395  // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
396  // since we want it to be fast as network peers may be able to trigger it repeatedly.
397  LOCK(m_events_mutex);
398 
399  unsigned char events_hash[32];
400  m_events_hasher.Finalize(events_hash);
401  hasher.Write(events_hash, 32);
402 
403  // Re-initialize the hasher with the finalized state to use later.
404  m_events_hasher.Reset();
405  m_events_hasher.Write(events_hash, 32);
406  }
407 
412  bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
413  {
414  assert(num <= 32);
415  unsigned char buf[64];
416  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
417  bool ret;
418  {
419  LOCK(m_mutex);
420  ret = (m_strongly_seeded |= strong_seed);
421  // Write the current state of the RNG into the hasher
422  hasher.Write(m_state, 32);
423  // Write a new counter number into the state
424  hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
425  ++m_counter;
426  // Finalize the hasher
427  hasher.Finalize(buf);
428  // Store the last 32 bytes of the hash output as new RNG state.
429  memcpy(m_state, buf + 32, 32);
430  }
431  // If desired, copy (up to) the first 32 bytes of the hash output as output.
432  if (num) {
433  assert(out != nullptr);
434  memcpy(out, buf, num);
435  }
436  // Best effort cleanup of internal state
437  hasher.Reset();
438  memory_cleanse(buf, 64);
439  return ret;
440  }
441 };
442 
443 RNGState& GetRNGState() noexcept
444 {
445  // This C++11 idiom relies on the guarantee that static variable are initialized
446  // on first call, even when multiple parallel calls are permitted.
447  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
448  return g_rng[0];
449 }
450 }
451 
452 /* A note on the use of noexcept in the seeding functions below:
453  *
454  * None of the RNG code should ever throw any exception.
455  */
456 
457 static void SeedTimestamp(CSHA512& hasher) noexcept
458 {
459  int64_t perfcounter = GetPerformanceCounter();
460  hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
461 }
462 
463 static void SeedFast(CSHA512& hasher) noexcept
464 {
465  unsigned char buffer[32];
466 
467  // Stack pointer to indirectly commit to thread/callstack
468  const unsigned char* ptr = buffer;
469  hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
470 
471  // Hardware randomness is very fast when available; use it always.
472  SeedHardwareFast(hasher);
473 
474  // High-precision timestamp
475  SeedTimestamp(hasher);
476 }
477 
478 static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
479 {
480  unsigned char buffer[32];
481 
482  // Everything that the 'fast' seeder includes
483  SeedFast(hasher);
484 
485  // OS randomness
486  GetOSRand(buffer);
487  hasher.Write(buffer, sizeof(buffer));
488 
489  // Add the events hasher into the mix
490  rng.SeedEvents(hasher);
491 
492  // High-precision timestamp.
493  //
494  // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
495  // benchmark of all the entropy gathering sources in this function).
496  SeedTimestamp(hasher);
497 }
498 
500 static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept
501 {
502  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
503  unsigned char strengthen_seed[32];
504  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
505  // Strengthen the seed, and feed it into hasher.
506  Strengthen(strengthen_seed, microseconds, hasher);
507 }
508 
509 static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
510 {
511  // Everything that the 'fast' seeder includes
512  SeedFast(hasher);
513 
514  // High-precision timestamp
515  SeedTimestamp(hasher);
516 
517  // Add the events hasher into the mix
518  rng.SeedEvents(hasher);
519 
520  // Dynamic environment data (performance monitoring, ...)
521  auto old_size = hasher.Size();
522  RandAddDynamicEnv(hasher);
523  LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
524 
525  // Strengthen for 10 ms
526  SeedStrengthen(hasher, rng, 10000);
527 }
528 
529 static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
530 {
531  // Gather 256 bits of hardware randomness, if available
532  SeedHardwareSlow(hasher);
533 
534  // Everything that the 'slow' seeder includes.
535  SeedSlow(hasher, rng);
536 
537  // Dynamic environment data (performance monitoring, ...)
538  auto old_size = hasher.Size();
539  RandAddDynamicEnv(hasher);
540 
541  // Static environment data
542  RandAddStaticEnv(hasher);
543  LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
544 
545  // Strengthen for 100 ms
546  SeedStrengthen(hasher, rng, 100000);
547 }
548 
549 enum class RNGLevel {
550  FAST,
551  SLOW,
552  PERIODIC,
553 };
554 
555 static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
556 {
557  // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
558  RNGState& rng = GetRNGState();
559 
560  assert(num <= 32);
561 
562  CSHA512 hasher;
563  switch (level) {
564  case RNGLevel::FAST:
565  SeedFast(hasher);
566  break;
567  case RNGLevel::SLOW:
568  SeedSlow(hasher, rng);
569  break;
570  case RNGLevel::PERIODIC:
571  SeedPeriodic(hasher, rng);
572  break;
573  }
574 
575  // Combine with and update state
576  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
577  // On the first invocation, also seed with SeedStartup().
578  CSHA512 startup_hasher;
579  SeedStartup(startup_hasher, rng);
580  rng.MixExtract(out, num, std::move(startup_hasher), true);
581  }
582 }
583 
584 void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
585 void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
586 void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
587 void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
588 
590 
591 uint64_t GetRand(uint64_t nMax) noexcept
592 {
594 }
595 
596 int GetRandInt(int nMax) noexcept
597 {
598  return GetRand(nMax);
599 }
600 
602 {
603  uint256 hash;
604  GetRandBytes((unsigned char*)&hash, sizeof(hash));
605  return hash;
606 }
607 
609 {
610  uint256 seed = GetRandHash();
611  rng.SetKey(seed.begin(), 32);
612  requires_seed = false;
613 }
614 
616 {
617  if (bytebuf_size < 32) {
618  FillByteBuffer();
619  }
620  uint256 ret;
621  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
622  bytebuf_size -= 32;
623  return ret;
624 }
625 
626 std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
627 {
628  if (requires_seed) RandomSeed();
629  std::vector<unsigned char> ret(len);
630  if (len > 0) {
631  rng.Keystream(ret.data(), len);
632  }
633  return ret;
634 }
635 
636 FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0)
637 {
638  rng.SetKey(seed.begin(), 32);
639 }
640 
642 {
643  uint64_t start = GetPerformanceCounter();
644 
645  /* This does not measure the quality of randomness, but it does test that
646  * GetOSRand() overwrites all 32 bytes of the output given a maximum
647  * number of tries.
648  */
649  static const ssize_t MAX_TRIES = 1024;
650  uint8_t data[NUM_OS_RANDOM_BYTES];
651  bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
652  int num_overwritten;
653  int tries = 0;
654  /* Loop until all bytes have been overwritten at least once, or max number tries reached */
655  do {
656  memset(data, 0, NUM_OS_RANDOM_BYTES);
657  GetOSRand(data);
658  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
659  overwritten[x] |= (data[x] != 0);
660  }
661 
662  num_overwritten = 0;
663  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
664  if (overwritten[x]) {
665  num_overwritten += 1;
666  }
667  }
668 
669  tries += 1;
670  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
671  if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
672 
673  // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
674  std::this_thread::sleep_for(std::chrono::milliseconds(1));
675  uint64_t stop = GetPerformanceCounter();
676  if (stop == start) return false;
677 
678  // We called GetPerformanceCounter. Use it as entropy.
679  CSHA512 to_add;
680  to_add.Write((const unsigned char*)&start, sizeof(start));
681  to_add.Write((const unsigned char*)&stop, sizeof(stop));
682  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
683 
684  return true;
685 }
686 
687 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
688 {
689  if (!fDeterministic) {
690  return;
691  }
692  uint256 seed;
693  rng.SetKey(seed.begin(), 32);
694 }
695 
697 {
698  requires_seed = from.requires_seed;
699  rng = from.rng;
700  std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
701  bytebuf_size = from.bytebuf_size;
702  bitbuf = from.bitbuf;
703  bitbuf_size = from.bitbuf_size;
704  from.requires_seed = true;
705  from.bytebuf_size = 0;
706  from.bitbuf_size = 0;
707  return *this;
708 }
709 
711 {
712  // Invoke RNG code to trigger initialization (if not already performed)
713  ProcRand(nullptr, 0, RNGLevel::FAST);
714 
716 }
SeedHardwareFast
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:189
RandFailure
static void RandFailure()
Definition: random.cpp:44
assert
assert(!tx.IsCoinBase())
FastRandomContext::rand256
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:615
ChaCha20::SetKey
void SetKey(const unsigned char *key, size_t keylen)
set key with flexible keylength; 256bit recommended *‍/
Definition: chacha20.cpp:24
sync.h
RNGLevel::FAST
@ FAST
Automatically called by GetRandBytes.
SeedFast
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:463
NUM_OS_RANDOM_BYTES
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:248
FastRandomContext::bytebuf
unsigned char bytebuf[64]
Definition: random.h:125
sha512.h
Strengthen
static void Strengthen(const unsigned char(&seed)[32], int microseconds, CSHA512 &hasher) noexcept
Use repeated SHA512 to strengthen the randomness in seed32, and feed into hasher.
Definition: random.cpp:225
cpuid.h
FastRandomContext::randbytes
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:626
randomenv.h
AnnotatedMixin< std::mutex >
FastRandomContext::FastRandomContext
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:687
GUARDED_BY
#define GUARDED_BY(x)
Definition: threadsafety.h:38
memory_cleanse
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
FastRandomContext::operator=
FastRandomContext & operator=(const FastRandomContext &)=delete
GetRand
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:591
CSHA512::Finalize
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha512.cpp:185
ChaCha20::Keystream
void Keystream(unsigned char *c, size_t bytes)
outputs the keystream of size <bytes> into
Definition: chacha20.cpp:74
RNGLevel::SLOW
@ SLOW
Automatically called by GetStrongRandBytes.
random.h
GetRandInt
int GetRandInt(int nMax) noexcept
Definition: random.cpp:596
SeedSlow
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:478
FastRandomContext::FillByteBuffer
void FillByteBuffer()
Definition: random.h:133
SeedStartup
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:529
CSHA512::OUTPUT_SIZE
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:20
RandAddEvent
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:587
SeedTimestamp
static void SeedTimestamp(CSHA512 &hasher) noexcept
Definition: random.cpp:457
compat.h
CSHA512::Reset
CSHA512 & Reset()
Definition: sha512.cpp:202
cleanse.h
GetRandHash
uint256 GetRandHash() noexcept
Definition: random.cpp:601
GetRandBytes
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:584
time.h
LogPrintf
#define LogPrintf(...)
Definition: logging.h:184
SeedHardwareSlow
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:200
FastRandomContext::RandomSeed
void RandomSeed()
Definition: random.cpp:608
GetOSRand
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:276
FastRandomContext::bytebuf_size
int bytebuf_size
Definition: random.h:126
uint256
256-bit opaque blob.
Definition: uint256.h:124
LogPrint
#define LogPrint(category,...)
Definition: logging.h:188
GetStrongRandBytes
void GetStrongRandBytes(unsigned char *buf, int num) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:585
RandomInit
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:710
CSHA512::Write
CSHA512 & Write(const unsigned char *data, size_t len)
Definition: sha512.cpp:159
g_mock_deterministic_tests
bool g_mock_deterministic_tests
Definition: random.cpp:589
secure.h
name
const char * name
Definition: rest.cpp:43
FastRandomContext::requires_seed
bool requires_seed
Definition: random.h:122
RandAddStaticEnv
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:307
sha256.h
BCLog::RAND
@ RAND
Definition: logging.h:51
stop
static RPCHelpMan stop()
Definition: server.cpp:161
RandAddDynamicEnv
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:226
LOCK
#define LOCK(cs)
Definition: sync.h:232
CSHA512
A hasher class for SHA-512.
Definition: sha512.h:12
SeedPeriodic
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:509
Random_SanityCheck
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:641
logging.h
CSHA256
A hasher class for SHA-256.
Definition: sha256.h:13
FastRandomContext::randrange
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:190
GetTimeMicros
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:122
FastRandomContext::rng
ChaCha20 rng
Definition: random.h:123
ProcRand
static void ProcRand(unsigned char *out, int num, RNGLevel level) noexcept
Definition: random.cpp:555
GetPerformanceCounter
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:50
InitHardwareRand
static void InitHardwareRand()
Definition: random.cpp:184
GetDevURandom
static void GetDevURandom(unsigned char *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:256
RandAddPeriodic
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:586
ReportHardwareRand
static void ReportHardwareRand()
Definition: random.cpp:185
RNGLevel
RNGLevel
Definition: random.cpp:549
SeedStrengthen
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition: random.cpp:500
base_blob::begin
unsigned char * begin()
Definition: uint256.h:58
FastRandomContext
Fast randomness source.
Definition: random.h:119
RNGLevel::PERIODIC
@ PERIODIC
Called by RandAddPeriodic()