Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ endif
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL)
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO)

bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
#
Expand Down
2 changes: 0 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1401,8 +1401,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!strErrors.str().empty())
return InitError(strErrors.str());

RandAddSeedPerfmon();

//// debug print
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
LogPrintf("nBestHeight = %d\n", chainActive.Height());
Expand Down
3 changes: 1 addition & 2 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,8 @@ bool CKey::Check(const unsigned char *vch) {
}

void CKey::MakeNewKey(bool fCompressedIn) {
RandAddSeedPerfmon();
do {
GetRandBytes(vch, sizeof(vch));
GetStrongRandBytes(vch, sizeof(vch));
} while (!Check(vch));
fValid = true;
fCompressed = fCompressedIn;
Expand Down
1 change: 0 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4547,7 +4547,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam

bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams)
{
RandAddSeedPerfmon();
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
Expand Down
66 changes: 63 additions & 3 deletions src/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@

#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()
#include "utilstrencodings.h" // for GetTime()

#include <stdlib.h>
#include <limits>

#ifndef WIN32
Expand All @@ -22,6 +25,12 @@
#include <openssl/err.h>
#include <openssl/rand.h>

static void RandFailure()
{
LogPrintf("Failed to read randomness, aborting\n");
abort();
}

static inline int64_t GetPerformanceCounter()
{
int64_t nCounter = 0;
Expand All @@ -43,7 +52,7 @@ void RandAddSeed()
memory_cleanse((void*)&nCounter, sizeof(nCounter));
}

void RandAddSeedPerfmon()
static void RandAddSeedPerfmon()
{
RandAddSeed();

Expand Down Expand Up @@ -83,14 +92,65 @@ 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);
if (!ret) {
RandFailure();
}
ret = CryptGenRandom(hProvider, 32, ent32);
if (!ret) {
RandFailure();
}
CryptReleaseContext(hProvider, 0);
#else
int f = open("/dev/urandom", O_RDONLY);
if (f == -1) {
RandFailure();
}
int have = 0;
do {
ssize_t n = read(f, ent32 + have, 32 - have);
if (n <= 0 || n + have > 32) {
RandFailure();
}
have += n;
} while (have < 32);
close(f);
#endif
}

void GetRandBytes(unsigned char* buf, int num)
{
if (RAND_bytes(buf, num) != 1) {
LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
assert(false);
RandFailure();
}
}

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)
Expand Down
11 changes: 7 additions & 4 deletions src/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@

#include <stdint.h>

/**
* Seed OpenSSL PRNG with additional entropy data
*/
/* Seed OpenSSL PRNG with additional entropy data */
void RandAddSeed();
void RandAddSeedPerfmon();

/**
* Functions to gather random data via the OpenSSL PRNG
Expand All @@ -24,6 +21,12 @@ uint64_t GetRand(uint64_t nMax);
int GetRandInt(int nMax);
uint256 GetRandHash();

/**
* Function to gather random data from multiple sources, failing whenever any
* of those source fail to provide a result.
*/
void GetStrongRandBytes(unsigned char* buf, int num);

/**
* Seed insecure_rand using the random pool.
* @param Deterministic Use a deterministic seed
Expand Down
8 changes: 2 additions & 6 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,16 +509,14 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return false;

CKeyingMaterial vMasterKey;
RandAddSeedPerfmon();

vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
GetStrongRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);

CMasterKey kMasterKey;
RandAddSeedPerfmon();

kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);

CCrypter crypter;
int64_t nStartTime = GetTimeMillis();
Expand Down Expand Up @@ -3147,8 +3145,6 @@ bool CWallet::InitLoadWallet()
if (fFirstRun)
{
// Create new keyUser and set as default key
RandAddSeedPerfmon();

CPubKey newDefaultKey;
if (walletInstance->GetKeyFromPool(newDefaultKey)) {
walletInstance->SetDefaultKey(newDefaultKey);
Expand Down