mirror of
https://github.com/dogecoin/dogecoin.git
synced 2026-01-31 10:30:52 +00:00
Use rdrand as entropy source on supported platforms
Includes squashed commits: 5155d1101eb4fc9d4d797b583bb29f71807bd10b a9e82f6512662054f64ed2bde590b2bb0831fc9d 674848fe1c43fb88870cf5ba16fca4e2524da793 Cherry-picked from: cb24c8539d1098d1a61605b452ecfa11a693320d
This commit is contained in:
parent
23bc7a072e
commit
60bd389823
@ -5,10 +5,12 @@
|
||||
#include "bench.h" // for BenchRunner
|
||||
#include "key.h" // for ECC_Start, ECC_Stop
|
||||
#include "util.h" // for SetupEnvironment, fPrintToDebugLog
|
||||
#include "random.h"
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
RandomInit();
|
||||
ECC_Start();
|
||||
SetupEnvironment();
|
||||
fPrintToDebugLog = false; // don't want to write to debug.log file
|
||||
|
||||
@ -1188,6 +1188,7 @@ bool AppInitSanityChecks()
|
||||
// ********************************************************* Step 4: sanity checks
|
||||
|
||||
// Initialize elliptic curve code
|
||||
RandomInit();
|
||||
ECC_Start();
|
||||
globalVerifyHandle.reset(new ECCVerifyHandle());
|
||||
|
||||
|
||||
@ -37,6 +37,10 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
@ -66,6 +70,61 @@ static inline int64_t GetPerformanceCounter()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||
static std::atomic<bool> hwrand_initialized{false};
|
||||
static bool rdrand_supported = false;
|
||||
static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
|
||||
static void RDRandInit()
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx & CPUID_F1_ECX_RDRAND)) {
|
||||
LogPrintf("Using RdRand as an additional entropy source\n");
|
||||
rdrand_supported = true;
|
||||
}
|
||||
hwrand_initialized.store(true);
|
||||
}
|
||||
#else
|
||||
static void RDRandInit() {}
|
||||
#endif
|
||||
|
||||
static bool GetHWRand(unsigned char* ent32) {
|
||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||
assert(hwrand_initialized.load(std::memory_order_relaxed));
|
||||
if (rdrand_supported) {
|
||||
uint8_t ok;
|
||||
// Not all assemblers support the rdrand instruction, write it in hex.
|
||||
#ifdef __i386__
|
||||
for (int iter = 0; iter < 4; ++iter) {
|
||||
uint32_t r1, r2;
|
||||
__asm__ volatile (".byte 0x0f, 0xc7, 0xf0;" // rdrand %eax
|
||||
".byte 0x0f, 0xc7, 0xf2;" // rdrand %edx
|
||||
"setc %2" :
|
||||
"=a"(r1), "=d"(r2), "=q"(ok) :: "cc");
|
||||
if (!ok) return false;
|
||||
WriteLE32(ent32 + 8 * iter, r1);
|
||||
WriteLE32(ent32 + 8 * iter + 4, r2);
|
||||
}
|
||||
#else
|
||||
uint64_t r1, r2, r3, r4;
|
||||
__asm__ volatile (".byte 0x48, 0x0f, 0xc7, 0xf0, " // rdrand %rax
|
||||
"0x48, 0x0f, 0xc7, 0xf3, " // rdrand %rbx
|
||||
"0x48, 0x0f, 0xc7, 0xf1, " // rdrand %rcx
|
||||
"0x48, 0x0f, 0xc7, 0xf2; " // rdrand %rdx
|
||||
"setc %4" :
|
||||
"=a"(r1), "=b"(r2), "=c"(r3), "=d"(r4), "=q"(ok) :: "cc");
|
||||
if (!ok) return false;
|
||||
WriteLE64(ent32, r1);
|
||||
WriteLE64(ent32 + 8, r2);
|
||||
WriteLE64(ent32 + 16, r3);
|
||||
WriteLE64(ent32 + 24, r4);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void RandAddSeed()
|
||||
{
|
||||
// Seed with CPU performance counter
|
||||
@ -228,6 +287,11 @@ void GetStrongRandBytes(unsigned char* out, int num)
|
||||
GetOSRand(buf);
|
||||
hasher.Write(buf, 32);
|
||||
|
||||
// Third source: HW RNG, if available.
|
||||
if (GetHWRand(buf)) {
|
||||
hasher.Write(buf, 32);
|
||||
}
|
||||
|
||||
// Produce output
|
||||
hasher.Finalize(buf);
|
||||
memcpy(out, buf, num);
|
||||
@ -345,3 +409,8 @@ FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDete
|
||||
uint256 seed;
|
||||
rng.SetKey(seed.begin(), 32);
|
||||
}
|
||||
|
||||
void RandomInit()
|
||||
{
|
||||
RDRandInit();
|
||||
}
|
||||
|
||||
@ -133,4 +133,7 @@ void GetOSRand(unsigned char *ent32);
|
||||
*/
|
||||
bool Random_SanityCheck();
|
||||
|
||||
/** Initialize the RNG. */
|
||||
void RandomInit();
|
||||
|
||||
#endif // BITCOIN_RANDOM_H
|
||||
|
||||
@ -43,6 +43,7 @@ static const int COINBASE_MATURITY = 60*4; // 4 hours of blocks
|
||||
|
||||
BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
|
||||
{
|
||||
RandomInit();
|
||||
ECC_Start();
|
||||
SetupEnvironment();
|
||||
SetupNetworking();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user