Bitcoin Core  0.18.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 <crypto/sha512.h>
9 #include <support/cleanse.h>
10 #ifdef WIN32
11 #include <compat.h> // for Windows API
12 #include <wincrypt.h>
13 #endif
14 #include <logging.h> // for LogPrint()
15 #include <sync.h> // for WAIT_LOCK
16 #include <util/time.h> // for GetTime()
17 
18 #include <stdlib.h>
19 #include <chrono>
20 #include <thread>
21 
23 
24 #ifndef WIN32
25 #include <fcntl.h>
26 #include <sys/time.h>
27 #endif
28 
29 #ifdef HAVE_SYS_GETRANDOM
30 #include <sys/syscall.h>
31 #include <linux/random.h>
32 #endif
33 #if defined(HAVE_GETENTROPY) || (defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX))
34 #include <unistd.h>
35 #endif
36 #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
37 #include <sys/random.h>
38 #endif
39 #ifdef HAVE_SYSCTL_ARND
40 #include <util/strencodings.h> // for ARRAYLEN
41 #include <sys/sysctl.h>
42 #endif
43 
44 #include <mutex>
45 
46 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
47 #include <cpuid.h>
48 #endif
49 
50 #include <openssl/err.h>
51 #include <openssl/rand.h>
52 #include <openssl/conf.h>
53 
54 [[noreturn]] static void RandFailure()
55 {
56  LogPrintf("Failed to read randomness, aborting\n");
57  std::abort();
58 }
59 
60 static inline int64_t GetPerformanceCounter() noexcept
61 {
62  // Read the hardware time stamp counter when available.
63  // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information.
64 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
65  return __rdtsc();
66 #elif !defined(_MSC_VER) && defined(__i386__)
67  uint64_t r = 0;
68  __asm__ volatile ("rdtsc" : "=A"(r)); // Constrain the r variable to the eax:edx pair.
69  return r;
70 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
71  uint64_t r1 = 0, r2 = 0;
72  __asm__ volatile ("rdtsc" : "=a"(r1), "=d"(r2)); // Constrain r1 to rax and r2 to rdx.
73  return (r2 << 32) | r1;
74 #else
75  // Fall back to using C++11 clock (usually microsecond or nanosecond precision)
76  return std::chrono::high_resolution_clock::now().time_since_epoch().count();
77 #endif
78 }
79 
80 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
81 static bool g_rdrand_supported = false;
82 static bool g_rdseed_supported = false;
83 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
84 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
85 #ifdef bit_RDRND
86 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND, "Unexpected value for bit_RDRND");
87 #endif
88 #ifdef bit_RDSEED
89 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED");
90 #endif
91 static void inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d)
92 {
93  // We can't use __get_cpuid as it doesn't support subleafs.
94 #ifdef __GNUC__
95  __cpuid_count(leaf, subleaf, a, b, c, d);
96 #else
97  __asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
98 #endif
99 }
100 
101 static void InitHardwareRand()
102 {
103  uint32_t eax, ebx, ecx, edx;
104  GetCPUID(1, 0, eax, ebx, ecx, edx);
105  if (ecx & CPUID_F1_ECX_RDRAND) {
106  g_rdrand_supported = true;
107  }
108  GetCPUID(7, 0, eax, ebx, ecx, edx);
109  if (ebx & CPUID_F7_EBX_RDSEED) {
110  g_rdseed_supported = true;
111  }
112 }
113 
114 static void ReportHardwareRand()
115 {
116  // This must be done in a separate function, as HWRandInit() may be indirectly called
117  // from global constructors, before logging is initialized.
118  if (g_rdseed_supported) {
119  LogPrintf("Using RdSeed as additional entropy source\n");
120  }
121  if (g_rdrand_supported) {
122  LogPrintf("Using RdRand as an additional entropy source\n");
123  }
124 }
125 
130 static uint64_t GetRdRand() noexcept
131 {
132  // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce this risk.
133 #ifdef __i386__
134  uint8_t ok;
135  uint32_t r1, r2;
136  for (int i = 0; i < 10; ++i) {
137  __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %eax
138  if (ok) break;
139  }
140  for (int i = 0; i < 10; ++i) {
141  __asm__ volatile (".byte 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdrand %eax
142  if (ok) break;
143  }
144  return (((uint64_t)r2) << 32) | r1;
145 #elif defined(__x86_64__) || defined(__amd64__)
146  uint8_t ok;
147  uint64_t r1;
148  for (int i = 0; i < 10; ++i) {
149  __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdrand %rax
150  if (ok) break;
151  }
152  return r1;
153 #else
154 #error "RdRand is only supported on x86 and x86_64"
155 #endif
156 }
157 
162 static uint64_t GetRdSeed() noexcept
163 {
164  // RdSeed may fail when the HW RNG is overloaded. Loop indefinitely until enough entropy is gathered,
165  // but pause after every failure.
166 #ifdef __i386__
167  uint8_t ok;
168  uint32_t r1, r2;
169  do {
170  __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %eax
171  if (ok) break;
172  __asm__ volatile ("pause");
173  } while(true);
174  do {
175  __asm__ volatile (".byte 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r2), "=q"(ok) :: "cc"); // rdseed %eax
176  if (ok) break;
177  __asm__ volatile ("pause");
178  } while(true);
179  return (((uint64_t)r2) << 32) | r1;
180 #elif defined(__x86_64__) || defined(__amd64__)
181  uint8_t ok;
182  uint64_t r1;
183  do {
184  __asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1" : "=a"(r1), "=q"(ok) :: "cc"); // rdseed %rax
185  if (ok) break;
186  __asm__ volatile ("pause");
187  } while(true);
188  return r1;
189 #else
190 #error "RdSeed is only supported on x86 and x86_64"
191 #endif
192 }
193 
194 #else
195 /* Access to other hardware random number generators could be added here later,
196  * assuming it is sufficiently fast (in the order of a few hundred CPU cycles).
197  * Slower sources should probably be invoked separately, and/or only from
198  * RandAddSeedSleep (which is called during idle background operation).
199  */
200 static void InitHardwareRand() {}
201 static void ReportHardwareRand() {}
202 #endif
203 
205 static void SeedHardwareFast(CSHA512& hasher) noexcept {
206 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
207  if (g_rdrand_supported) {
208  uint64_t out = GetRdRand();
209  hasher.Write((const unsigned char*)&out, sizeof(out));
210  return;
211  }
212 #endif
213 }
214 
216 static void SeedHardwareSlow(CSHA512& hasher) noexcept {
217 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
218  // When we want 256 bits of entropy, prefer RdSeed over RdRand, as it's
219  // guaranteed to produce independent randomness on every call.
220  if (g_rdseed_supported) {
221  for (int i = 0; i < 4; ++i) {
222  uint64_t out = GetRdSeed();
223  hasher.Write((const unsigned char*)&out, sizeof(out));
224  }
225  return;
226  }
227  // When falling back to RdRand, XOR the result of 1024 results.
228  // This guarantees a reseeding occurs between each.
229  if (g_rdrand_supported) {
230  for (int i = 0; i < 4; ++i) {
231  uint64_t out = 0;
232  for (int j = 0; j < 1024; ++j) out ^= GetRdRand();
233  hasher.Write((const unsigned char*)&out, sizeof(out));
234  }
235  return;
236  }
237 #endif
238 }
239 
241 static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA512& hasher) noexcept
242 {
243  CSHA512 inner_hasher;
244  inner_hasher.Write(seed, sizeof(seed));
245 
246  // Hash loop
247  unsigned char buffer[64];
248  int64_t stop = GetTimeMicros() + microseconds;
249  do {
250  for (int i = 0; i < 1000; ++i) {
251  inner_hasher.Finalize(buffer);
252  inner_hasher.Reset();
253  inner_hasher.Write(buffer, sizeof(buffer));
254  }
255  // Benchmark operation and feed it into outer hasher.
256  int64_t perf = GetPerformanceCounter();
257  hasher.Write((const unsigned char*)&perf, sizeof(perf));
258  } while (GetTimeMicros() < stop);
259 
260  // Produce output from inner state and feed it to outer hasher.
261  inner_hasher.Finalize(buffer);
262  hasher.Write(buffer, sizeof(buffer));
263  // Try to clean up.
264  inner_hasher.Reset();
265  memory_cleanse(buffer, sizeof(buffer));
266 }
267 
268 static void RandAddSeedPerfmon(CSHA512& hasher)
269 {
270 #ifdef WIN32
271  // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
272  // Seed with the entire set of perfmon data
273 
274  // This can take up to 2 seconds, so only do it every 10 minutes
275  static int64_t nLastPerfmon;
276  if (GetTime() < nLastPerfmon + 10 * 60)
277  return;
278  nLastPerfmon = GetTime();
279 
280  std::vector<unsigned char> vData(250000, 0);
281  long ret = 0;
282  unsigned long nSize = 0;
283  const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
284  while (true) {
285  nSize = vData.size();
286  ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize);
287  if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
288  break;
289  vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
290  }
291  RegCloseKey(HKEY_PERFORMANCE_DATA);
292  if (ret == ERROR_SUCCESS) {
293  hasher.Write(vData.data(), nSize);
294  memory_cleanse(vData.data(), nSize);
295  } else {
296  // Performance data is only a best-effort attempt at improving the
297  // situation when the OS randomness (and other sources) aren't
298  // adequate. As a result, failure to read it is isn't considered critical,
299  // so we don't call RandFailure().
300  // TODO: Add logging when the logger is made functional before global
301  // constructors have been invoked.
302  }
303 #endif
304 }
305 
306 #ifndef WIN32
307 
310 static void GetDevURandom(unsigned char *ent32)
311 {
312  int f = open("/dev/urandom", O_RDONLY);
313  if (f == -1) {
314  RandFailure();
315  }
316  int have = 0;
317  do {
318  ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
319  if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
320  close(f);
321  RandFailure();
322  }
323  have += n;
324  } while (have < NUM_OS_RANDOM_BYTES);
325  close(f);
326 }
327 #endif
328 
330 void GetOSRand(unsigned char *ent32)
331 {
332 #if defined(WIN32)
333  HCRYPTPROV hProvider;
334  int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
335  if (!ret) {
336  RandFailure();
337  }
338  ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32);
339  if (!ret) {
340  RandFailure();
341  }
342  CryptReleaseContext(hProvider, 0);
343 #elif defined(HAVE_SYS_GETRANDOM)
344  /* Linux. From the getrandom(2) man page:
345  * "If the urandom source has been initialized, reads of up to 256 bytes
346  * will always return as many bytes as requested and will not be
347  * interrupted by signals."
348  */
349  int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
350  if (rv != NUM_OS_RANDOM_BYTES) {
351  if (rv < 0 && errno == ENOSYS) {
352  /* Fallback for kernel <3.17: the return value will be -1 and errno
353  * ENOSYS if the syscall is not available, in that case fall back
354  * to /dev/urandom.
355  */
356  GetDevURandom(ent32);
357  } else {
358  RandFailure();
359  }
360  }
361 #elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
362  /* On OpenBSD this can return up to 256 bytes of entropy, will return an
363  * error if more are requested.
364  * The call cannot return less than the requested number of bytes.
365  getentropy is explicitly limited to openbsd here, as a similar (but not
366  the same) function may exist on other platforms via glibc.
367  */
368  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
369  RandFailure();
370  }
371 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
372  // We need a fallback for OSX < 10.12
373  if (&getentropy != nullptr) {
374  if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
375  RandFailure();
376  }
377  } else {
378  GetDevURandom(ent32);
379  }
380 #elif defined(HAVE_SYSCTL_ARND)
381  /* FreeBSD and similar. It is possible for the call to return less
382  * bytes than requested, so need to read in a loop.
383  */
384  static const int name[2] = {CTL_KERN, KERN_ARND};
385  int have = 0;
386  do {
387  size_t len = NUM_OS_RANDOM_BYTES - have;
388  if (sysctl(name, ARRAYLEN(name), ent32 + have, &len, nullptr, 0) != 0) {
389  RandFailure();
390  }
391  have += len;
392  } while (have < NUM_OS_RANDOM_BYTES);
393 #else
394  /* Fall back to /dev/urandom if there is no specific method implemented to
395  * get system entropy for this OS.
396  */
397  GetDevURandom(ent32);
398 #endif
399 }
400 
401 void LockingCallbackOpenSSL(int mode, int i, const char* file, int line);
402 
403 namespace {
404 
405 class RNGState {
406  Mutex m_mutex;
407  /* The RNG state consists of 256 bits of entropy, taken from the output of
408  * one operation's SHA512 output, and fed as input to the next one.
409  * Carrying 256 bits of entropy should be sufficient to guarantee
410  * unpredictability as long as any entropy source was ever unpredictable
411  * to an attacker. To protect against situations where an attacker might
412  * observe the RNG's state, fresh entropy is always mixed when
413  * GetStrongRandBytes is called.
414  */
415  unsigned char m_state[32] GUARDED_BY(m_mutex) = {0};
416  uint64_t m_counter GUARDED_BY(m_mutex) = 0;
417  bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
418  std::unique_ptr<Mutex[]> m_mutex_openssl;
419 
420 public:
421  RNGState() noexcept
422  {
424 
425  // Init OpenSSL library multithreading support
426  m_mutex_openssl.reset(new Mutex[CRYPTO_num_locks()]);
427  CRYPTO_set_locking_callback(LockingCallbackOpenSSL);
428 
429  // OpenSSL can optionally load a config file which lists optional loadable modules and engines.
430  // We don't use them so we don't require the config. However some of our libs may call functions
431  // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
432  // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
433  // that the config appears to have been loaded and there are no modules/engines available.
434  OPENSSL_no_config();
435  }
436 
437  ~RNGState()
438  {
439  // Securely erase the memory used by the OpenSSL PRNG
440  RAND_cleanup();
441  // Shutdown OpenSSL library multithreading support
442  CRYPTO_set_locking_callback(nullptr);
443  }
444 
449  bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept
450  {
451  assert(num <= 32);
452  unsigned char buf[64];
453  static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
454  bool ret;
455  {
456  LOCK(m_mutex);
457  ret = (m_strongly_seeded |= strong_seed);
458  // Write the current state of the RNG into the hasher
459  hasher.Write(m_state, 32);
460  // Write a new counter number into the state
461  hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
462  ++m_counter;
463  // Finalize the hasher
464  hasher.Finalize(buf);
465  // Store the last 32 bytes of the hash output as new RNG state.
466  memcpy(m_state, buf + 32, 32);
467  }
468  // If desired, copy (up to) the first 32 bytes of the hash output as output.
469  if (num) {
470  assert(out != nullptr);
471  memcpy(out, buf, num);
472  }
473  // Best effort cleanup of internal state
474  hasher.Reset();
475  memory_cleanse(buf, 64);
476  return ret;
477  }
478 
479  Mutex& GetOpenSSLMutex(int i) { return m_mutex_openssl[i]; }
480 };
481 
482 RNGState& GetRNGState() noexcept
483 {
484  // This C++11 idiom relies on the guarantee that static variable are initialized
485  // on first call, even when multiple parallel calls are permitted.
486  static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
487  return g_rng[0];
488 }
489 }
490 
491 void LockingCallbackOpenSSL(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
492 {
493  RNGState& rng = GetRNGState();
494 
495  if (mode & CRYPTO_LOCK) {
496  rng.GetOpenSSLMutex(i).lock();
497  } else {
498  rng.GetOpenSSLMutex(i).unlock();
499  }
500 }
501 
502 /* A note on the use of noexcept in the seeding functions below:
503  *
504  * None of the RNG code should ever throw any exception, with the sole exception
505  * of MilliSleep in SeedSleep, which can (and does) support interruptions which
506  * cause a boost::thread_interrupted to be thrown.
507  *
508  * This means that SeedSleep, and all functions that invoke it are throwing.
509  * However, we know that GetRandBytes() and GetStrongRandBytes() never trigger
510  * this sleeping logic, so they are noexcept. The same is true for all the
511  * GetRand*() functions that use GetRandBytes() indirectly.
512  *
513  * TODO: After moving away from interruptible boost-based thread management,
514  * everything can become noexcept here.
515  */
516 
517 static void SeedTimestamp(CSHA512& hasher) noexcept
518 {
519  int64_t perfcounter = GetPerformanceCounter();
520  hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
521 }
522 
523 static void SeedFast(CSHA512& hasher) noexcept
524 {
525  unsigned char buffer[32];
526 
527  // Stack pointer to indirectly commit to thread/callstack
528  const unsigned char* ptr = buffer;
529  hasher.Write((const unsigned char*)&ptr, sizeof(ptr));
530 
531  // Hardware randomness is very fast when available; use it always.
532  SeedHardwareFast(hasher);
533 
534  // High-precision timestamp
535  SeedTimestamp(hasher);
536 }
537 
538 static void SeedSlow(CSHA512& hasher) noexcept
539 {
540  unsigned char buffer[32];
541 
542  // Everything that the 'fast' seeder includes
543  SeedFast(hasher);
544 
545  // OS randomness
546  GetOSRand(buffer);
547  hasher.Write(buffer, sizeof(buffer));
548 
549  // OpenSSL RNG (for now)
550  RAND_bytes(buffer, sizeof(buffer));
551  hasher.Write(buffer, sizeof(buffer));
552 
553  // High-precision timestamp.
554  //
555  // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
556  // benchmark of all the entropy gathering sources in this function).
557  SeedTimestamp(hasher);
558 }
559 
561 static void SeedStrengthen(CSHA512& hasher, RNGState& rng) noexcept
562 {
563  static std::atomic<int64_t> last_strengthen{0};
564  int64_t last_time = last_strengthen.load();
565  int64_t current_time = GetTimeMicros();
566  if (current_time > last_time + 60000000) { // Only run once a minute
567  // Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
568  unsigned char strengthen_seed[32];
569  rng.MixExtract(strengthen_seed, sizeof(strengthen_seed), CSHA512(hasher), false);
570  // Strengthen it for 10ms (100ms on first run), and feed it into hasher.
571  Strengthen(strengthen_seed, last_time == 0 ? 100000 : 10000, hasher);
572  last_strengthen = current_time;
573  }
574 }
575 
576 static void SeedSleep(CSHA512& hasher, RNGState& rng)
577 {
578  // Everything that the 'fast' seeder includes
579  SeedFast(hasher);
580 
581  // High-precision timestamp
582  SeedTimestamp(hasher);
583 
584  // Sleep for 1ms
585  MilliSleep(1);
586 
587  // High-precision timestamp after sleeping (as we commit to both the time before and after, this measures the delay)
588  SeedTimestamp(hasher);
589 
590  // Windows performance monitor data (once every 10 minutes)
591  RandAddSeedPerfmon(hasher);
592 
593  // Strengthen every minute
594  SeedStrengthen(hasher, rng);
595 }
596 
597 static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
598 {
599 #ifdef WIN32
600  RAND_screen();
601 #endif
602 
603  // Gather 256 bits of hardware randomness, if available
604  SeedHardwareSlow(hasher);
605 
606  // Everything that the 'slow' seeder includes.
607  SeedSlow(hasher);
608 
609  // Windows performance monitor data.
610  RandAddSeedPerfmon(hasher);
611 
612  // Strengthen
613  SeedStrengthen(hasher, rng);
614 }
615 
616 enum class RNGLevel {
617  FAST,
618  SLOW,
619  SLEEP,
620 };
621 
622 static void ProcRand(unsigned char* out, int num, RNGLevel level)
623 {
624  // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
625  RNGState& rng = GetRNGState();
626 
627  assert(num <= 32);
628 
629  CSHA512 hasher;
630  switch (level) {
631  case RNGLevel::FAST:
632  SeedFast(hasher);
633  break;
634  case RNGLevel::SLOW:
635  SeedSlow(hasher);
636  break;
637  case RNGLevel::SLEEP:
638  SeedSleep(hasher, rng);
639  break;
640  }
641 
642  // Combine with and update state
643  if (!rng.MixExtract(out, num, std::move(hasher), false)) {
644  // On the first invocation, also seed with SeedStartup().
645  CSHA512 startup_hasher;
646  SeedStartup(startup_hasher, rng);
647  rng.MixExtract(out, num, std::move(startup_hasher), true);
648  }
649 
650  // For anything but the 'fast' level, feed the resulting RNG output (after an additional hashing step) back into OpenSSL.
651  if (level != RNGLevel::FAST) {
652  unsigned char buf[64];
653  CSHA512().Write(out, num).Finalize(buf);
654  RAND_add(buf, sizeof(buf), num);
655  memory_cleanse(buf, 64);
656  }
657 }
658 
659 void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); }
660 void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
661 void RandAddSeedSleep() { ProcRand(nullptr, 0, RNGLevel::SLEEP); }
662 
664 
665 uint64_t GetRand(uint64_t nMax) noexcept
666 {
668 }
669 
670 std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
671 {
672  return std::chrono::microseconds{GetRand(duration_max.count())};
673 }
674 
675 int GetRandInt(int nMax) noexcept
676 {
677  return GetRand(nMax);
678 }
679 
681 {
682  uint256 hash;
683  GetRandBytes((unsigned char*)&hash, sizeof(hash));
684  return hash;
685 }
686 
688 {
689  uint256 seed = GetRandHash();
690  rng.SetKey(seed.begin(), 32);
691  requires_seed = false;
692 }
693 
695 {
696  if (bytebuf_size < 32) {
697  FillByteBuffer();
698  }
699  uint256 ret;
700  memcpy(ret.begin(), bytebuf + 64 - bytebuf_size, 32);
701  bytebuf_size -= 32;
702  return ret;
703 }
704 
705 std::vector<unsigned char> FastRandomContext::randbytes(size_t len)
706 {
707  if (requires_seed) RandomSeed();
708  std::vector<unsigned char> ret(len);
709  if (len > 0) {
710  rng.Keystream(&ret[0], len);
711  }
712  return ret;
713 }
714 
715 FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0)
716 {
717  rng.SetKey(seed.begin(), 32);
718 }
719 
721 {
722  uint64_t start = GetPerformanceCounter();
723 
724  /* This does not measure the quality of randomness, but it does test that
725  * OSRandom() overwrites all 32 bytes of the output given a maximum
726  * number of tries.
727  */
728  static const ssize_t MAX_TRIES = 1024;
729  uint8_t data[NUM_OS_RANDOM_BYTES];
730  bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
731  int num_overwritten;
732  int tries = 0;
733  /* Loop until all bytes have been overwritten at least once, or max number tries reached */
734  do {
735  memset(data, 0, NUM_OS_RANDOM_BYTES);
736  GetOSRand(data);
737  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
738  overwritten[x] |= (data[x] != 0);
739  }
740 
741  num_overwritten = 0;
742  for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
743  if (overwritten[x]) {
744  num_overwritten += 1;
745  }
746  }
747 
748  tries += 1;
749  } while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
750  if (num_overwritten != NUM_OS_RANDOM_BYTES) return false; /* If this failed, bailed out after too many tries */
751 
752  // Check that GetPerformanceCounter increases at least during a GetOSRand() call + 1ms sleep.
753  std::this_thread::sleep_for(std::chrono::milliseconds(1));
754  uint64_t stop = GetPerformanceCounter();
755  if (stop == start) return false;
756 
757  // We called GetPerformanceCounter. Use it as entropy.
758  CSHA512 to_add;
759  to_add.Write((const unsigned char*)&start, sizeof(start));
760  to_add.Write((const unsigned char*)&stop, sizeof(stop));
761  GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false);
762 
763  return true;
764 }
765 
766 FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0)
767 {
768  if (!fDeterministic) {
769  return;
770  }
771  uint256 seed;
772  rng.SetKey(seed.begin(), 32);
773 }
774 
776 {
777  requires_seed = from.requires_seed;
778  rng = from.rng;
779  std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
780  bytebuf_size = from.bytebuf_size;
781  bitbuf = from.bitbuf;
782  bitbuf_size = from.bitbuf_size;
783  from.requires_seed = true;
784  from.bytebuf_size = 0;
785  from.bitbuf_size = 0;
786  return *this;
787 }
788 
790 {
791  // Invoke RNG code to trigger initialization (if not already performed)
792  ProcRand(nullptr, 0, RNGLevel::FAST);
793 
795 }
static const int NUM_OS_RANDOM_BYTES
Definition: random.h:224
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:789
void GetOSRand(unsigned char *ent32)
Get 32 bytes of system entropy.
Definition: random.cpp:330
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:53
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:665
void RandAddSeedSleep()
Sleep for 1ms, gather entropy from various sources, and feed them to the PRNG state.
Definition: random.cpp:661
FastRandomContext & operator=(const FastRandomContext &)=delete
uint256 GetRandHash() noexcept
Definition: random.cpp:680
static void SeedHardwareSlow(CSHA512 &hasher) noexcept
Add 256 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:216
#define ARRAYLEN(array)
Utilities for converting data from/to strings.
Definition: strencodings.h:19
static void GetDevURandom(unsigned char *ent32)
Fallback: get 32 bytes of system entropy from /dev/urandom.
Definition: random.cpp:310
void MilliSleep(int64_t n)
Definition: time.cpp:75
uint256 rand256() noexcept
generate a random uint256.
Definition: random.cpp:694
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:144
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:659
FastRandomContext(bool fDeterministic=false) noexcept
Definition: random.cpp:766
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:241
unsigned char * begin()
Definition: uint256.h:55
std::chrono::microseconds GetRandMicros(std::chrono::microseconds duration_max) noexcept
Definition: random.cpp:670
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha512.cpp:185
RNGLevel
Definition: random.cpp:616
static void SeedFast(CSHA512 &hasher) noexcept
Definition: random.cpp:523
void LockingCallbackOpenSSL(int mode, int i, const char *file, int line)
Definition: random.cpp:491
static void RandFailure()
Definition: random.cpp:54
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:660
#define LOCK(cs)
Definition: sync.h:182
const char * name
Definition: rest.cpp:39
static void SeedStrengthen(CSHA512 &hasher, RNGState &rng) noexcept
Extract entropy from rng, strengthen it, and feed it into hasher.
Definition: random.cpp:561
Fast randomness source.
Definition: random.h:100
CSHA512 & Reset()
Definition: sha512.cpp:202
static void SeedStartup(CSHA512 &hasher, RNGState &rng) noexcept
Definition: random.cpp:597
void RandomSeed()
Definition: random.cpp:687
Automatically called by GetStrongRandBytes.
static constexpr size_t OUTPUT_SIZE
Definition: sha512.h:20
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: time.cpp:62
bool requires_seed
Definition: random.h:102
256-bit opaque blob.
Definition: uint256.h:121
Automatically called by GetRandBytes.
static void ReportHardwareRand()
Definition: random.cpp:201
static void SeedSlow(CSHA512 &hasher) noexcept
Definition: random.cpp:538
void * memcpy(void *a, const void *b, size_t c)
CSHA512 & Write(const unsigned char *data, size_t len)
Definition: sha512.cpp:159
static void ProcRand(unsigned char *out, int num, RNGLevel level)
Definition: random.cpp:622
#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:663
static void SeedHardwareFast(CSHA512 &hasher) noexcept
Add 64 bits of entropy gathered from hardware to hasher.
Definition: random.cpp:205
static void SeedSleep(CSHA512 &hasher, RNGState &rng)
Definition: random.cpp:576
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: time.cpp:20
int GetRandInt(int nMax) noexcept
Definition: random.cpp:675
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:720
static void InitHardwareRand()
Definition: random.cpp:200
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:167
Called by RandAddSeedSleep()
std::vector< unsigned char > randbytes(size_t len)
Generate random bytes.
Definition: random.cpp:705
UniValue stop(const JSONRPCRequest &jsonRequest)
Definition: server.cpp:156
static void RandAddSeedPerfmon(CSHA512 &hasher)
Definition: random.cpp:268
static int64_t GetPerformanceCounter() noexcept
Definition: random.cpp:60
static void SeedTimestamp(CSHA512 &hasher) noexcept
Definition: random.cpp:517