|
|
|
@ -5,9 +5,11 @@
@@ -5,9 +5,11 @@
|
|
|
|
|
|
|
|
|
|
#include "random.h" |
|
|
|
|
|
|
|
|
|
#include "crypto/sha512.h" |
|
|
|
|
#include "support/cleanse.h" |
|
|
|
|
#ifdef WIN32 |
|
|
|
|
#include "compat.h" // for Windows API |
|
|
|
|
#include <wincrypt.h> |
|
|
|
|
#endif |
|
|
|
|
#include "serialize.h" // for begin_ptr(vec) |
|
|
|
|
#include "util.h" // for LogPrint() |
|
|
|
@ -43,7 +45,7 @@ void RandAddSeed()
@@ -43,7 +45,7 @@ void RandAddSeed()
|
|
|
|
|
memory_cleanse((void*)&nCounter, sizeof(nCounter)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void RandAddSeedPerfmon() |
|
|
|
|
static void RandAddSeedPerfmon() |
|
|
|
|
{ |
|
|
|
|
RandAddSeed(); |
|
|
|
|
|
|
|
|
@ -83,6 +85,29 @@ void RandAddSeedPerfmon()
@@ -83,6 +85,29 @@ void RandAddSeedPerfmon()
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Get 32 bytes of system entropy. */ |
|
|
|
|
static void GetOSRand(unsigned char *ent32) |
|
|
|
|
{ |
|
|
|
|
#ifdef WIN32 |
|
|
|
|
HCRYPTPROV hProvider; |
|
|
|
|
int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); |
|
|
|
|
assert(ret); |
|
|
|
|
ret = CryptGenRandom(hProvider, 32, ent32); |
|
|
|
|
assert(ret); |
|
|
|
|
CryptReleaseContext(hProvider, 0); |
|
|
|
|
#else |
|
|
|
|
int f = open("/dev/urandom", O_RDONLY); |
|
|
|
|
assert(f != -1); |
|
|
|
|
int have = 0; |
|
|
|
|
do { |
|
|
|
|
ssize_t n = read(f, ent32 + have, 32 - have); |
|
|
|
|
assert(n > 0 && n <= 32 - have); |
|
|
|
|
have += n; |
|
|
|
|
} while (have < 32); |
|
|
|
|
close(f); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GetRandBytes(unsigned char* buf, int num) |
|
|
|
|
{ |
|
|
|
|
if (RAND_bytes(buf, num) != 1) { |
|
|
|
@ -91,6 +116,27 @@ void GetRandBytes(unsigned char* buf, int num)
@@ -91,6 +116,27 @@ void GetRandBytes(unsigned char* buf, int num)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GetStrongRandBytes(unsigned char* out, int num) |
|
|
|
|
{ |
|
|
|
|
assert(num <= 32); |
|
|
|
|
CSHA512 hasher; |
|
|
|
|
unsigned char buf[64]; |
|
|
|
|
|
|
|
|
|
// First source: OpenSSL's RNG
|
|
|
|
|
RandAddSeedPerfmon(); |
|
|
|
|
GetRandBytes(buf, 32); |
|
|
|
|
hasher.Write(buf, 32); |
|
|
|
|
|
|
|
|
|
// Second source: OS RNG
|
|
|
|
|
GetOSRand(buf); |
|
|
|
|
hasher.Write(buf, 32); |
|
|
|
|
|
|
|
|
|
// Produce output
|
|
|
|
|
hasher.Finalize(buf); |
|
|
|
|
memcpy(out, buf, num); |
|
|
|
|
memory_cleanse(buf, 64); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint64_t GetRand(uint64_t nMax) |
|
|
|
|
{ |
|
|
|
|
if (nMax == 0) |
|
|
|
|