31 #ifdef HAVE_SYS_GETRANDOM
32 #include <sys/syscall.h>
33 #include <linux/random.h>
35 #if defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
37 #include <sys/random.h>
39 #ifdef HAVE_SYSCTL_ARND
40 #include <sys/sysctl.h>
45 LogPrintf(
"Failed to read randomness, aborting\n");
53 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
55 #elif !defined(_MSC_VER) && defined(__i386__)
57 __asm__
volatile (
"rdtsc" :
"=A"(r));
59 #elif !defined(_MSC_VER) && (defined(__x86_64__) || defined(__amd64__))
60 uint64_t r1 = 0, r2 = 0;
61 __asm__
volatile (
"rdtsc" :
"=a"(r1),
"=d"(r2));
62 return (r2 << 32) | r1;
65 return std::chrono::high_resolution_clock::now().time_since_epoch().count();
70 static bool g_rdrand_supported =
false;
71 static bool g_rdseed_supported =
false;
72 static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
73 static constexpr uint32_t CPUID_F7_EBX_RDSEED = 0x00040000;
75 static_assert(CPUID_F1_ECX_RDRAND == bit_RDRND,
"Unexpected value for bit_RDRND");
78 static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED,
"Unexpected value for bit_RDSEED");
83 uint32_t eax, ebx, ecx, edx;
84 GetCPUID(1, 0, eax, ebx, ecx, edx);
85 if (ecx & CPUID_F1_ECX_RDRAND) {
86 g_rdrand_supported =
true;
88 GetCPUID(7, 0, eax, ebx, ecx, edx);
89 if (ebx & CPUID_F7_EBX_RDSEED) {
90 g_rdseed_supported =
true;
98 if (g_rdseed_supported) {
99 LogPrintf(
"Using RdSeed as additional entropy source\n");
101 if (g_rdrand_supported) {
102 LogPrintf(
"Using RdRand as an additional entropy source\n");
110 static uint64_t GetRdRand() noexcept
118 uint32_t r1 = 0, r2 = 0;
119 for (
int i = 0; i < 10; ++i) {
120 __asm__
volatile (
".byte 0x0f, 0xc7, 0xf0; setc %1" :
"=a"(r1),
"=q"(ok) ::
"cc");
123 for (
int i = 0; i < 10; ++i) {
124 __asm__
volatile (
".byte 0x0f, 0xc7, 0xf0; setc %1" :
"=a"(r2),
"=q"(ok) ::
"cc");
127 return (((uint64_t)r2) << 32) | r1;
128 #elif defined(__x86_64__) || defined(__amd64__)
131 for (
int i = 0; i < 10; ++i) {
132 __asm__
volatile (
".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" :
"=a"(r1),
"=q"(ok) ::
"cc");
137 #error "RdRand is only supported on x86 and x86_64"
145 static uint64_t GetRdSeed() noexcept
153 __asm__
volatile (
".byte 0x0f, 0xc7, 0xf8; setc %1" :
"=a"(r1),
"=q"(ok) ::
"cc");
155 __asm__
volatile (
"pause");
158 __asm__
volatile (
".byte 0x0f, 0xc7, 0xf8; setc %1" :
"=a"(r2),
"=q"(ok) ::
"cc");
160 __asm__
volatile (
"pause");
162 return (((uint64_t)r2) << 32) | r1;
163 #elif defined(__x86_64__) || defined(__amd64__)
167 __asm__
volatile (
".byte 0x48, 0x0f, 0xc7, 0xf8; setc %1" :
"=a"(r1),
"=q"(ok) ::
"cc");
169 __asm__
volatile (
"pause");
173 #error "RdSeed is only supported on x86 and x86_64"
189 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
190 if (g_rdrand_supported) {
191 uint64_t out = GetRdRand();
192 hasher.Write((
const unsigned char*)&out,
sizeof(out));
200 #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
203 if (g_rdseed_supported) {
204 for (
int i = 0; i < 4; ++i) {
205 uint64_t out = GetRdSeed();
206 hasher.Write((
const unsigned char*)&out,
sizeof(out));
212 if (g_rdrand_supported) {
213 for (
int i = 0; i < 4; ++i) {
215 for (
int j = 0; j < 1024; ++j) out ^= GetRdRand();
216 hasher.Write((
const unsigned char*)&out,
sizeof(out));
224 static void Strengthen(
const unsigned char (&seed)[32],
int microseconds,
CSHA512& hasher) noexcept
227 inner_hasher.
Write(seed,
sizeof(seed));
230 unsigned char buffer[64];
233 for (
int i = 0; i < 1000; ++i) {
235 inner_hasher.
Reset();
236 inner_hasher.
Write(buffer,
sizeof(buffer));
240 hasher.Write((
const unsigned char*)&perf,
sizeof(perf));
245 hasher.Write(buffer,
sizeof(buffer));
247 inner_hasher.
Reset();
257 int f = open(
"/dev/urandom", O_RDONLY);
278 HCRYPTPROV hProvider;
279 int ret = CryptAcquireContextW(&hProvider,
nullptr,
nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
287 CryptReleaseContext(hProvider, 0);
288 #elif defined(HAVE_SYS_GETRANDOM)
296 if (rv < 0 && errno == ENOSYS) {
306 #elif defined(__OpenBSD__)
316 #elif defined(HAVE_GETENTROPY_RAND) && defined(MAC_OSX)
324 #elif defined(HAVE_SYSCTL_ARND)
328 static int name[2] = {CTL_KERN, KERN_ARND};
332 if (sysctl(
name, std::size(
name), ent32 + have, &len,
nullptr, 0) != 0) {
359 unsigned char m_state[32]
GUARDED_BY(m_mutex) = {0};
361 bool m_strongly_seeded
GUARDED_BY(m_mutex) =
false;
363 Mutex m_events_mutex;
376 void AddEvent(uint32_t event_info) noexcept
378 LOCK(m_events_mutex);
380 m_events_hasher.Write((
const unsigned char *)&event_info,
sizeof(event_info));
384 m_events_hasher.Write((
const unsigned char*)&perfcounter,
sizeof(perfcounter));
390 void SeedEvents(
CSHA512& hasher) noexcept
394 LOCK(m_events_mutex);
396 unsigned char events_hash[32];
397 m_events_hasher.Finalize(events_hash);
398 hasher.Write(events_hash, 32);
401 m_events_hasher.Reset();
402 m_events_hasher.Write(events_hash, 32);
409 bool MixExtract(
unsigned char* out,
size_t num,
CSHA512&& hasher,
bool strong_seed) noexcept
412 unsigned char buf[64];
413 static_assert(
sizeof(buf) ==
CSHA512::OUTPUT_SIZE,
"Buffer needs to have hasher's output size");
417 ret = (m_strongly_seeded |= strong_seed);
419 hasher.Write(m_state, 32);
421 hasher.Write((
const unsigned char*)&m_counter,
sizeof(m_counter));
424 hasher.Finalize(buf);
426 memcpy(m_state, buf + 32, 32);
431 memcpy(out, buf, num);
440 RNGState& GetRNGState() noexcept
444 static std::vector<RNGState, secure_allocator<RNGState>> g_rng(1);
457 hasher.Write((
const unsigned char*)&perfcounter,
sizeof(perfcounter));
462 unsigned char buffer[32];
465 const unsigned char* ptr = buffer;
466 hasher.Write((
const unsigned char*)&ptr,
sizeof(ptr));
477 unsigned char buffer[32];
484 hasher.Write(buffer,
sizeof(buffer));
487 rng.SeedEvents(hasher);
500 unsigned char strengthen_seed[32];
501 rng.MixExtract(strengthen_seed,
sizeof(strengthen_seed),
CSHA512(hasher),
false);
503 Strengthen(strengthen_seed, microseconds, hasher);
515 rng.SeedEvents(hasher);
518 auto old_size = hasher.Size();
520 LogPrint(
BCLog::RAND,
"Feeding %i bytes of dynamic environment data into RNG\n", hasher.Size() - old_size);
535 auto old_size = hasher.Size();
540 LogPrint(
BCLog::RAND,
"Feeding %i bytes of environment data into RNG\n", hasher.Size() - old_size);
555 RNGState& rng = GetRNGState();
573 if (!rng.MixExtract(out, num, std::move(hasher),
false)) {
577 rng.MixExtract(out, num, std::move(startup_hasher),
true);
584 void RandAddEvent(
const uint32_t event_info) noexcept { GetRNGState().AddEvent(event_info); }
626 std::vector<unsigned char> ret(len);
635 rng.SetKey(seed.begin(), 32);
646 static const ssize_t MAX_TRIES = 1024;
656 overwritten[x] |= (data[x] != 0);
661 if (overwritten[x]) {
662 num_overwritten += 1;
671 std::this_thread::sleep_for(std::chrono::milliseconds(1));
673 if (
stop == start)
return false;
677 to_add.
Write((
const unsigned char*)&start,
sizeof(start));
679 GetRNGState().MixExtract(
nullptr, 0, std::move(to_add),
false);
686 if (!fDeterministic) {
690 rng.SetKey(seed.
begin(), 32);
697 std::copy(std::begin(from.bytebuf), std::end(from.bytebuf), std::begin(bytebuf));
698 bytebuf_size = from.bytebuf_size;
699 bitbuf = from.bitbuf;
700 bitbuf_size = from.bitbuf_size;
701 from.requires_seed =
true;
702 from.bytebuf_size = 0;
703 from.bitbuf_size = 0;
715 std::chrono::microseconds
GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
717 double unscaled = -std::log1p(
GetRand(uint64_t{1} << 48) * -0.0000000000000035527136788 );
718 return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);