Bitcoin Core  0.19.99
P2P Digital Currency
random.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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 <sync.h> // for Mutex
18 #include <util/time.h> // for GetTimeMicros()
19 
20 #include <stdlib.h>
21 #include <thread>
22 
23 #include <randomenv.h>
24 
26 
27 #ifndef WIN32
28 #include <fcntl.h>
29 #include <sys/time.h>
30 #endif
31 
32 #ifdef HAVE_SYS_GETRANDOM
33 #include <sys/syscall.h>
34 #include <linux/random.h>
35 #endif
36 #if defined(HAVE_GETENTROPY) || (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
37 #include <unistd.h>
38 #endif
39 #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
40 #include <sys/random.h>
41 #endif
42 #ifdef HAVE_SYSCTL_ARND
43 #include <util/strencodings.h> // for ARRAYLEN
44 #include <sys/sysctl.h>
45 #endif
46 
47 [[noreturn]] static void RandFailure()
48 {
49  LogPrintf("Failed to read randomness, aborting\n");
50  std::abort();
51 }
52 
53 static inline int64_t GetPerformanceCounter() noexcept
54 {
55  // Read the hardware time stamp counter when available.
56  // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
57 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
58  return __rdtsc();
59 #elif !defined(_MSC_VER) && defined(__i386__)
60  uint64_t r = 0;
61  __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
62  return r;
63 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
64  uint64_t r1 = 0, r2 = 0;
65  __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
66  return (r2 << 32) | r1;
67 #else
68  // Fall back to using C++11 clock (usually microsecond or nanosecond precision)
69  return std::chrono::high_resolution_clock::now().time_since_epoch().count();
70 #endif
71 }
72 
73 #ifdef HAVE_GETCPUID
74 static bool g_rdrand_supported = false;
75 static bool g_rdseed_supported = false;
76 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
77 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
78 #ifdef bit_RDRND
79 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
80 #endif
81 #ifdef bit_RDSEED
82 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
83 #endif
84 
85 static void InitHardwareRand()
86 {
87  uint32_t eax, ebx, ecx, edx;
88  GetCPUID(1, 0, eax, ebx, ecx, edx);
89  if (ecx & CPUID_F1_ECX_RDRAND) {
90  g_rdrand_supported = true;
91  }
92  GetCPUID(7, 0, eax, ebx, ecx, edx);
93  if (ebx & CPUID_F7_EBX_RDSEED) {
94  g_rdseed_supported = true;
95  }
96 }
97 
98 static void ReportHardwareRand()
99 {
100  // This must be done in a separate function, as InitHardwareRand() may be indirectly called
101  // from global constructors, before logging is initialized.
102  if (g_rdseed_supported) {
103  LogPrintf("Using RdSeed as additional entropy source\n");
104  }
105  if (g_rdrand_supported) {
106  LogPrintf("Using RdRand as an additional entropy source\n");
107  }
108 }
109 
114 static uint64_t GetRdRand() noexcept
115 {
116  // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
117 #ifdef __i386__
118  uint8_t ok;
119  uint32_t r1, r2;
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;
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 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
318  /* getentropy() is available on macOS 10.12 and later.
319  */
320  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
321  RandFailure();
322  }
323 #elif defined(HAVE_SYSCTL_ARND)
324  /* FreeBSD, NetBSD and similar. It is possible for the call to return less
325  * bytes than requested, so need to read in a loop.
326  */
327  static int name[2] = {CTL_KERN, KERN_ARND};
328  int have = 0;
329  do {
330  size_t len = NUM_OS_RANDOM_BYTES - have;
331  if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 0) {
332  RandFailure();
333  }
334  have += len;
335  } while (have < NUM_OS_RANDOM_BYTES);
336 #else
337  /* Fall back to /dev/urandom if there is no specific method implemented to
338  * get system entropy for this OS.
339  */
340  GetDevURandom(ent32);
341 #endif
342 }
343 
344 namespace {
345 
346 class RNGState {
347  Mutex m_mutex;
348  /* The RNG state consists of 256 bits of entropy, taken from the output of
349  * one operation's SHA512 output, and fed as input to the next one.
350  * Carrying 256 bits of entropy should be sufficient to guarantee
351  * unpredictability as long as any entropy source was ever unpredictable
352  * to an attacker. To protect against situations where an attacker might
353  * observe the RNG's state, fresh entropy is always mixed when
354  * GetStrongRandBytes is called.
355  */
356  unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
357  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
358  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
359 
360  Mutex m_events_mutex;
361  CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
362 
363 public:
364  RNGState() noexcept
365  {
367  }
368 
369  ~RNGState()
370  {
371  }
372 
373  void AddEvent(uint32_t event_info) noexcept
374  {
375  LOCK(m_events_mutex);
376 
377  m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
378  // Get the low four bytes of the performance counter. This translates to roughly the
379  // subsecond part.
380  uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
381  m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
382  }
383 
387  void SeedEvents(CSHA512& hasher) noexcept
388  {
389  // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
390  // since we want it to be fast as network peers may be able to trigger it repeatedly.
391  LOCK(m_events_mutex);
392 
393  unsigned char events_hash[32];
394  m_events_hasher.Finalize(events_hash);
395  hasher.Write(events_hash, 32);
396 
397  // Re-initialize the hasher with the finalized state to use later.
398  m_events_hasher.Reset();
399  m_events_hasher.Write(events_hash, 32);
400  }
401 
406  bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
407  {
408  assert(num <= 32);
409  unsigned char buf[64];
410  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
411  bool ret;
412  {
413  LOCK(m_mutex);
414  ret = (m_strongly_seeded |= strong_seed);
415  // Write the current state of the RNG into the hasher
416  hasher.Write(m_state, 32);
417  // Write a new counter number into the state
418  hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
419  ++m_counter;
420  // Finalize the hasher
421  hasher.Finalize(buf);
422  // Store the last 32 bytes of the hash output as new RNG state.
423  memcpy(m_state, buf + 32, 32);
424  }
425  // If desired, copy (up to) the first 32 bytes of the hash output as output.
426  if (num) {
427  assert(out != nullptr);
428  memcpy(out, buf, num);
429  }
430  // Best effort cleanup of internal state
431  hasher.Reset();
432  memory_cleanse(buf, 64);
433  return ret;
434  }
435 };
436 
437 RNGState& GetRNGState() noexcept
438 {
439  // This C++11 idiom relies on the guarantee that static variable are initialized
440  // on first call, even when multiple parallel calls are permitted.
441  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
442  return g_rng[0];
443 }
444 }
445 
446 /* A note on the use of noexcept in the seeding functions below:
447  *
448  * None of the RNG code should ever throw any exception.
449  */
450 
451 static void SeedTimestamp(CSHA512& hasher) noexcept
452 {
453  int64_t perfcounter = GetPerformanceCounter();
454  hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
455 }
456 
457 static void SeedFast(CSHA512& hasher) noexcept
458 {
459  unsigned char buffer[32];
460 
461  // Stack pointer to indirectly commit to thread/callstack
462  const unsigned char* ptr = buffer;
463  hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
464 
465  // Hardware randomness is very fast when available; use it always.
466  SeedHardwareFast(hasher);
467 
468  // High-precision timestamp
469  SeedTimestamp(hasher);
470 }
471 
472 static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
473 {
474  unsigned char buffer[32];
475 
476  // Everything that the 'fast' seeder includes
477  SeedFast(hasher);
478 
479  // OS randomness
480  GetOSRand(buffer);
481  hasher.Write(buffer, sizeof(buffer));
482 
483  // Add the events hasher into the mix
484  rng.SeedEvents(hasher);
485 
486  // High-precision timestamp.
487  //
488  // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
489  // benchmark of all the entropy gathering sources in this function).
490  SeedTimestamp(hasher);
491 }
492 
494 static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept
495 {
496  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
497  unsigned char strengthen_seed[32];
498  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
499  // Strengthen the seed, and feed it into hasher.
500  Strengthen(strengthen_seed, microseconds, hasher);
501 }
502 
503 static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
504 {
505  // Everything that the 'fast' seeder includes
506  SeedFast(hasher);
507 
508  // High-precision timestamp
509  SeedTimestamp(hasher);
510 
511  // Add the events hasher into the mix
512  rng.SeedEvents(hasher);
513 
514  // Dynamic environment data (performance monitoring, ...)
515  auto old_size = hasher.Size();
516  RandAddDynamicEnv(hasher);
517  LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
518 
519  // Strengthen for 10 ms
520  SeedStrengthen(hasher, rng, 10000);
521 }
522 
523 static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
524 {
525  // Gather 256 bits of hardware randomness, if available
526  SeedHardwareSlow(hasher);
527 
528  // Everything that the 'slow' seeder includes.
529  SeedSlow(hasher, rng);
530 
531  // Dynamic environment data (performance monitoring, ...)
532  auto old_size = hasher.Size();
533  RandAddDynamicEnv(hasher);
534 
535  // Static environment data
536  RandAddStaticEnv(hasher);
537  LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
538 
539  // Strengthen for 100 ms
540  SeedStrengthen(hasher, rng, 100000);
541 }
542 
543 enum class RNGLevel {
544  FAST,
545  SLOW,
546  PERIODIC,
547 };
548 
549 static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
550 {
551  // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
552  RNGState& rng = GetRNGState();
553 
554  assert(num <= 32);
555 
556  CSHA512 hasher;
557  switch (level) {
558  case RNGLevel::FAST:
559  SeedFast(hasher);
560  break;
561  case RNGLevel::SLOW:
562  SeedSlow(hasher, rng);
563  break;
564  case RNGLevel::PERIODIC:
565  SeedPeriodic(hasher, rng);
566  break;
567  }
568 
569  // Combine with and update state
570  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
571  // On the first invocation, also seed with SeedStartup().
572  CSHA512 startup_hasher;
573  SeedStartup(startup_hasher, rng);
574  rng.MixExtract(out, num, std::move(startup_hasher), true);
575  }
576 }
577 
578 void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
579 void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
580 void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
581 void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
582 
584 
585 uint64_t GetRand(uint64_t nMax) noexcept
586 {
588 }
589 
590 std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
591 {
592  return std::chrono::microseconds{GetRand(duration_max.count())};
593 }
594 
595 int GetRandInt(int nMax) noexcept
596 {
597  return GetRand(nMax);
598 }
599 
601 {
602  uint256 hash;
603  GetRandBytes((unsigned char*)&hash, sizeof(hash));
604  return hash;
605 }
606 
608 {
609  uint256 seed = GetRandHash();
610  rng.SetKey(seed.begin(), 32);
611  requires_seed = false;
612 }
613 
615 {
616  if (bytebuf_size < 32) {
617  FillByteBuffer();
618  }
619  uint256 ret;
620  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
621  bytebuf_size -= 32;
622  return ret;
623 }
624 
625 std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
626 {
627  if (requires_seed) RandomSeed();
628  std::vector<unsigned char> ret(len);
629  if (len > 0) {
630  rng.Keystream(&ret[0], len);
631  }
632  return ret;
633 }
634 
635 FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0)
636 {
637  rng.SetKey(seed.begin(), 32);
638 }
639 
641 {
642  uint64_t start = GetPerformanceCounter();
643 
644  /* This does not measure the quality of randomness, but it does test that
645  * GetOSRand() overwrites all 32 bytes of the output given a maximum
646  * number of tries.
647  */
648  static const ssize_t MAX_TRIES = 1024;
649  uint8_t data[NUM_OS_RANDOM_BYTES];
650  bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
651  int num_overwritten;
652  int tries = 0;
653  /* Loop until all bytes have been overwritten at least once, or max number tries reached */
654  do {
655  memset(data, 0, NUM_OS_RANDOM_BYTES);
656  GetOSRand(data);
657  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
658  overwritten[x] |= (data[x] != 0);
659  }
660 
661  num_overwritten = 0;
662  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
663  if (overwritten[x]) {
664  num_overwritten += 1;
665  }
666  }
667 
668  tries += 1;
669  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
670  if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
671 
672  // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
673  std::this_thread::sleep_for(std::chrono::milliseconds(1));
674  uint64_t stop = GetPerformanceCounter();
675  if (stop == start) return false;
676 
677  // We called GetPerformanceCounter. Use it as entropy.
678  CSHA512 to_add;
679  to_add.Write((const unsigned char*)&start, sizeof(start));
680  to_add.Write((const unsigned char*)&stop, sizeof(stop));
681  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
682 
683  return true;
684 }
685 
686 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
687 {
688  if (!fDeterministic) {
689  return;
690  }
691  uint256 seed;
692  rng.SetKey(seed.begin(), 32);
693 }
694 
696 {
697  requires_seed = from.requires_seed;
698  rng = from.rng;
699  std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
700  bytebuf_size = from.bytebuf_size;
701  bitbuf = from.bitbuf;
702  bitbuf_size = from.bitbuf_size;
703  from.requires_seed = true;
704  from.bytebuf_size = 0;
705  from.bitbuf_size = 0;
706  return *this;
707 }
708 
710 {
711  // Invoke RNG code to trigger initialization (if not already performed)
712  ProcRand(nullptr, 0, RNGLevel::FAST);
713 
715 }
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:235
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:709
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:276
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:581
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:585
#define LogPrint(category,...)
Definition: logging.h:179
FastRandomContext & operator=(const FastRandomContext &)=delete
uint256 GetRandHash() noexcept
Definition: random.cpp:600
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:200
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
Definition: strencodings.h:19
static void ProcRand(unsigned char *out, int num, RNGLevel level) noexcept
Definition: random.cpp:549
static void GetDevURandom(unsigned char *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:256
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:614
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:163
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:580
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:578
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:686
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
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng, int microseconds) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition: random.cpp:494
unsigned char * begin()
Definition: uint256.h:54
Called by RandAddPeriodic()
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:590
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha512.cpp:185
RNGLevel
Definition: random.cpp:543
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:457
static void RandFailure()
Definition: random.cpp:47
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
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:579
#define LOCK(cs)
Definition: sync.h:218
const char * name
Definition: rest.cpp:40
Fast randomness source.
Definition: random.h:106
CSHA512 & Reset()
Definition: sha512.cpp:202
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:523
void RandomSeed()
Definition: random.cpp:607
Automatically called by GetStrongRandBytes.
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:20
static void SeedPeriodic(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:503
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:65
bool requires_seed
Definition: random.h:109
256-bit opaque blob.
Definition: uint256.h:120
Automatically called by GetRandBytes.
static void ReportHardwareRand()
Definition: random.cpp:185
static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:472
void * memcpy(void *a, const void *b, size_t c)
CSHA512 & Write(const unsigned char *data, size_t len)
Definition: sha512.cpp:159
#define GUARDED_BY(x)
Definition: threadsafety.h:38
A hasher class for SHA-512.
Definition: sha512.h:12
bool g_mock_deterministic_tests
Definition: random.cpp:583
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:189
A hasher class for SHA-256.
Definition: sha256.h:13
void RandAddStaticEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that does not change over time.
Definition: randomenv.cpp:306
int GetRandInt(int nMax) noexcept
Definition: random.cpp:595
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:640
static void InitHardwareRand()
Definition: random.cpp:184
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:177
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:625
UniValue stop(const JSONRPCRequest &jsonRequest)
Definition: server.cpp:154
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:53
static void SeedTimestamp(CSHA512 &hasher) noexcept
Definition: random.cpp:451
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:225