mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 06:28:31 +01:00
Always require OS randomness when generating secret keys
This commit is contained in:
@@ -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()
|
||||
memory_cleanse((void*)&nCounter, sizeof(nCounter));
|
||||
}
|
||||
|
||||
void RandAddSeedPerfmon()
|
||||
static void RandAddSeedPerfmon()
|
||||
{
|
||||
RandAddSeed();
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user