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-2018 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 GetTime()
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  // We need a fallback for OSX < 10.12
319  if (&getentropy != nullptr) {
320  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
321  RandFailure();
322  }
323  } else {
324  GetDevURandom(ent32);
325  }
326 #elif defined(HAVE_SYSCTL_ARND)
327  /* FreeBSD and similar. It is possible for the call to return less
328  * bytes than requested, so need to read in a loop.
329  */
330  static const int name[2] = {CTL_KERN, KERN_ARND};
331  int have = 0;
332  do {
333  size_t len = NUM_OS_RANDOM_BYTES - have;
334  if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 0) {
335  RandFailure();
336  }
337  have += len;
338  } while (have < NUM_OS_RANDOM_BYTES);
339 #else
340  /* Fall back to /dev/urandom if there is no specific method implemented to
341  * get system entropy for this OS.
342  */
343  GetDevURandom(ent32);
344 #endif
345 }
346 
347 namespace {
348 
349 class RNGState {
350  Mutex m_mutex;
351  /* The RNG state consists of 256 bits of entropy, taken from the output of
352  * one operation's SHA512 output, and fed as input to the next one.
353  * Carrying 256 bits of entropy should be sufficient to guarantee
354  * unpredictability as long as any entropy source was ever unpredictable
355  * to an attacker. To protect against situations where an attacker might
356  * observe the RNG's state, fresh entropy is always mixed when
357  * GetStrongRandBytes is called.
358  */
359  unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
360  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
361  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
362 
363  Mutex m_events_mutex;
364  CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
365 
366 public:
367  RNGState() noexcept
368  {
370  }
371 
372  ~RNGState()
373  {
374  }
375 
376  void AddEvent(uint32_t event_info) noexcept
377  {
378  LOCK(m_events_mutex);
379 
380  m_events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
381  // Get the low four bytes of the performance counter. This translates to roughly the
382  // subsecond part.
383  uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
384  m_events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
385  }
386 
390  void SeedEvents(CSHA512& hasher) noexcept
391  {
392  // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
393  // since we want it to be fast as network peers may be able to trigger it repeatedly.
394  LOCK(m_events_mutex);
395 
396  unsigned char events_hash[32];
397  m_events_hasher.Finalize(events_hash);
398  hasher.Write(events_hash, 32);
399 
400  // Re-initialize the hasher with the finalized state to use later.
401  m_events_hasher.Reset();
402  m_events_hasher.Write(events_hash, 32);
403  }
404 
409  bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
410  {
411  assert(num <= 32);
412  unsigned char buf[64];
413  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
414  bool ret;
415  {
416  LOCK(m_mutex);
417  ret = (m_strongly_seeded |= strong_seed);
418  // Write the current state of the RNG into the hasher
419  hasher.Write(m_state, 32);
420  // Write a new counter number into the state
421  hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
422  ++m_counter;
423  // Finalize the hasher
424  hasher.Finalize(buf);
425  // Store the last 32 bytes of the hash output as new RNG state.
426  memcpy(m_state, buf + 32, 32);
427  }
428  // If desired, copy (up to) the first 32 bytes of the hash output as output.
429  if (num) {
430  assert(out != nullptr);
431  memcpy(out, buf, num);
432  }
433  // Best effort cleanup of internal state
434  hasher.Reset();
435  memory_cleanse(buf, 64);
436  return ret;
437  }
438 };
439 
440 RNGState& GetRNGState() noexcept
441 {
442  // This C++11 idiom relies on the guarantee that static variable are initialized
443  // on first call, even when multiple parallel calls are permitted.
444  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
445  return g_rng[0];
446 }
447 }
448 
449 /* A note on the use of noexcept in the seeding functions below:
450  *
451  * None of the RNG code should ever throw any exception.
452  */
453 
454 static void SeedTimestamp(CSHA512& hasher) noexcept
455 {
456  int64_t perfcounter = GetPerformanceCounter();
457  hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
458 }
459 
460 static void SeedFast(CSHA512& hasher) noexcept
461 {
462  unsigned char buffer[32];
463 
464  // Stack pointer to indirectly commit to thread/callstack
465  const unsigned char* ptr = buffer;
466  hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
467 
468  // Hardware randomness is very fast when available; use it always.
469  SeedHardwareFast(hasher);
470 
471  // High-precision timestamp
472  SeedTimestamp(hasher);
473 }
474 
475 static void SeedSlow(CSHA512& hasher, RNGState& rng) noexcept
476 {
477  unsigned char buffer[32];
478 
479  // Everything that the 'fast' seeder includes
480  SeedFast(hasher);
481 
482  // OS randomness
483  GetOSRand(buffer);
484  hasher.Write(buffer, sizeof(buffer));
485 
486  // Add the events hasher into the mix
487  rng.SeedEvents(hasher);
488 
489  // High-precision timestamp.
490  //
491  // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
492  // benchmark of all the entropy gathering sources in this function).
493  SeedTimestamp(hasher);
494 }
495 
497 static void SeedStrengthen(CSHA512& hasher, RNGState& rng, int microseconds) noexcept
498 {
499  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
500  unsigned char strengthen_seed[32];
501  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
502  // Strengthen the seed, and feed it into hasher.
503  Strengthen(strengthen_seed, microseconds, hasher);
504 }
505 
506 static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
507 {
508  // Everything that the 'fast' seeder includes
509  SeedFast(hasher);
510 
511  // High-precision timestamp
512  SeedTimestamp(hasher);
513 
514  // Add the events hasher into the mix
515  rng.SeedEvents(hasher);
516 
517  // Dynamic environment data (performance monitoring, ...)
518  auto old_size = hasher.Size();
519  RandAddDynamicEnv(hasher);
520  LogPrint(BCLog::RAND, "Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
521 
522  // Strengthen for 10 ms
523  SeedStrengthen(hasher, rng, 10000);
524 }
525 
526 static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
527 {
528  // Gather 256 bits of hardware randomness, if available
529  SeedHardwareSlow(hasher);
530 
531  // Everything that the 'slow' seeder includes.
532  SeedSlow(hasher, rng);
533 
534  // Dynamic environment data (performance monitoring, ...)
535  auto old_size = hasher.Size();
536  RandAddDynamicEnv(hasher);
537 
538  // Static environment data
539  RandAddStaticEnv(hasher);
540  LogPrint(BCLog::RAND, "Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
541 
542  // Strengthen for 100 ms
543  SeedStrengthen(hasher, rng, 100000);
544 }
545 
546 enum class RNGLevel {
547  FAST,
548  SLOW,
549  PERIODIC,
550 };
551 
552 static void ProcRand(unsigned char* out, int num, RNGLevel level) noexcept
553 {
554  // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
555  RNGState& rng = GetRNGState();
556 
557  assert(num <= 32);
558 
559  CSHA512 hasher;
560  switch (level) {
561  case RNGLevel::FAST:
562  SeedFast(hasher);
563  break;
564  case RNGLevel::SLOW:
565  SeedSlow(hasher, rng);
566  break;
567  case RNGLevel::PERIODIC:
568  SeedPeriodic(hasher, rng);
569  break;
570  }
571 
572  // Combine with and update state
573  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
574  // On the first invocation, also seed with SeedStartup().
575  CSHA512 startup_hasher;
576  SeedStartup(startup_hasher, rng);
577  rng.MixExtract(out, num, std::move(startup_hasher), true);
578  }
579 }
580 
581 void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
582 void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
583 void RandAddPeriodic() noexcept { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
584 void RandAddEvent(const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
585 
587 
588 uint64_t GetRand(uint64_t nMax) noexcept
589 {
591 }
592 
593 std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
594 {
595  return std::chrono::microseconds{GetRand(duration_max.count())};
596 }
597 
598 int GetRandInt(int nMax) noexcept
599 {
600  return GetRand(nMax);
601 }
602 
604 {
605  uint256 hash;
606  GetRandBytes((unsigned char*)&hash, sizeof(hash));
607  return hash;
608 }
609 
611 {
612  uint256 seed = GetRandHash();
613  rng.SetKey(seed.begin(), 32);
614  requires_seed = false;
615 }
616 
618 {
619  if (bytebuf_size < 32) {
620  FillByteBuffer();
621  }
622  uint256 ret;
623  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
624  bytebuf_size -= 32;
625  return ret;
626 }
627 
628 std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
629 {
630  if (requires_seed) RandomSeed();
631  std::vector<unsigned char> ret(len);
632  if (len > 0) {
633  rng.Keystream(&ret[0], len);
634  }
635  return ret;
636 }
637 
638 FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0)
639 {
640  rng.SetKey(seed.begin(), 32);
641 }
642 
644 {
645  uint64_t start = GetPerformanceCounter();
646 
647  /* This does not measure the quality of randomness, but it does test that
648  * GetOSRand() overwrites all 32 bytes of the output given a maximum
649  * number of tries.
650  */
651  static const ssize_t MAX_TRIES = 1024;
652  uint8_t data[NUM_OS_RANDOM_BYTES];
653  bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
654  int num_overwritten;
655  int tries = 0;
656  /* Loop until all bytes have been overwritten at least once, or max number tries reached */
657  do {
658  memset(data, 0, NUM_OS_RANDOM_BYTES);
659  GetOSRand(data);
660  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
661  overwritten[x] |= (data[x] != 0);
662  }
663 
664  num_overwritten = 0;
665  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
666  if (overwritten[x]) {
667  num_overwritten += 1;
668  }
669  }
670 
671  tries += 1;
672  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
673  if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
674 
675  // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
676  std::this_thread::sleep_for(std::chrono::milliseconds(1));
677  uint64_t stop = GetPerformanceCounter();
678  if (stop == start) return false;
679 
680  // We called GetPerformanceCounter. Use it as entropy.
681  CSHA512 to_add;
682  to_add.Write((const unsigned char*)&start, sizeof(start));
683  to_add.Write((const unsigned char*)&stop, sizeof(stop));
684  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
685 
686  return true;
687 }
688 
689 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
690 {
691  if (!fDeterministic) {
692  return;
693  }
694  uint256 seed;
695  rng.SetKey(seed.begin(), 32);
696 }
697 
699 {
700  requires_seed = from.requires_seed;
701  rng = from.rng;
702  std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
703  bytebuf_size = from.bytebuf_size;
704  bitbuf = from.bitbuf;
705  bitbuf_size = from.bitbuf_size;
706  from.requires_seed = true;
707  from.bytebuf_size = 0;
708  from.bitbuf_size = 0;
709  return *this;
710 }
711 
713 {
714  // Invoke RNG code to trigger initialization (if not already performed)
715  ProcRand(nullptr, 0, RNGLevel::FAST);
716 
718 }
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:231
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:712
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:584
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:588
#define LogPrint(category,...)
Definition: logging.h:178
FastRandomContext & operator=(const FastRandomContext &)=delete
uint256 GetRandHash() noexcept
Definition: random.cpp:603
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:552
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:617
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:162
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:583
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:581
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:689
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:497
unsigned char * begin()
Definition: uint256.h:54
Called by RandAddPeriodic()
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:593
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha512.cpp:185
RNGLevel
Definition: random.cpp:546
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:460
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:582
#define LOCK(cs)
Definition: sync.h:180
const char * name
Definition: rest.cpp:38
Fast randomness source.
Definition: random.h:106
CSHA512 & Reset()
Definition: sha512.cpp:202
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:526
void RandomSeed()
Definition: random.cpp:610
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:506
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:62
bool requires_seed
Definition: random.h:108
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:475
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:586
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:325
int GetRandInt(int nMax) noexcept
Definition: random.cpp:598
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:643
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:173
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:628
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:454
void RandAddDynamicEnv(CSHA512 &hasher)
Gather non-cryptographic environment data that changes over time.
Definition: randomenv.cpp:230