Skip to content

Commit

Permalink
Remove deprecated random number generator functions
Browse files Browse the repository at this point in the history
This commit changes CInit to check for proper RNG seeding and use
RAND_poll() if necessary.

It removes RandAddSeed() RandAddSeedPerfmon() and also the use
of RAND_screen.
  • Loading branch information
jamescowens committed Jul 15, 2021
1 parent 3014f62 commit 6df1dc5
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 63 deletions.
4 changes: 0 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1245,8 +1245,6 @@ bool AppInit2(ThreadHandlerPtr threads)
if (fFirstRun)
{
// Create new keyUser and set as default key
RandAddSeedPerfmon();

CPubKey newDefaultKey;
if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) {
pwalletMain->SetDefaultKey(newDefaultKey);
Expand Down Expand Up @@ -1358,8 +1356,6 @@ bool AppInit2(ThreadHandlerPtr threads)
if (!CheckDiskSpace())
return false;

RandAddSeedPerfmon();

if (!GRC::Initialize(threads, pindexBest)) {
return false;
}
Expand Down
2 changes: 0 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2950,8 +2950,6 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv)

bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();

LogPrint(BCLog::LogFlags::NOISY, "received: %s from %s (%" PRIszu " bytes)", strCommand, pfrom->addrName, vRecv.size());

if (strCommand == "aries")
Expand Down
10 changes: 0 additions & 10 deletions src/qt/winshutdownmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM

MSG *pMsg = static_cast<MSG *>(pMessage);

// Seed OpenSSL PRNG with Windows event data (e.g. mouse movements and other user interactions)
if (RAND_event(pMsg->message, pMsg->wParam, pMsg->lParam) == 0) {
// Warn only once as this is performance-critical
static bool warned = false;
if (!warned) {
LogPrintf("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__);
warned = true;
}
}

switch(pMsg->message)
{
case WM_QUERYENDSESSION:
Expand Down
60 changes: 19 additions & 41 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,27 @@ class CInit
ppmutexOpenSSL[i] = new CCriticalSection();
CRYPTO_set_locking_callback(locking_callback);

#ifdef WIN32
// Seed OpenSSL PRNG with current contents of the screen
RAND_screen();
#endif
// Check whether OpenSSL random number generator is properly seeded. If not, attempt to seed using RAND_poll().
// Note that in versions of OpenSSL in the depends in Gridcoin (currently 1.1.1+), and modern Unix distros (using
// openSSL 1.1.1+ or modern Windows operating systems with the equivalent of /dev/urandom, the random number
// generator is automatically seeded on init, and periodically reseeded from trusted OS random sources. It is
// not necessary to manually reseed the RNG. Here we implement a check via RAND_status() to ensure the RNG
// is properly seeded. If not, we try 10 times (probably excessive) to seed the RNG via openSSL's entropy sources,
// breaking as soon as the return from RAND_poll() becomes 1 (successfully seeded). If this falls through, we abort
// the application as we cannot have a non-functioning RNG.
bool seed_successful = RAND_status();
if (!seed_successful) {
for (unsigned int i = 0; i < 10; ++i)
{
seed_successful = RAND_poll();

// Seed OpenSSL PRNG with performance counter
RandAddSeed();
if (seed_successful) break;
}

if (!seed_successful) std::abort();
}
}

~CInit()
{
// Securely erase the memory used by the PRNG
Expand All @@ -106,41 +119,6 @@ class CInit
}
instance_of_cinit;

void RandAddSeed()
{
// Seed with CPU performance counter
int64_t nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
memset(&nCounter, 0, sizeof(nCounter));
}

void RandAddSeedPerfmon()
{
RandAddSeed();

// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if ( GetAdjustedTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetAdjustedTime();

#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data
unsigned char pdata[250000];
memset(pdata, 0, sizeof(pdata));
unsigned long nSize = sizeof(pdata);
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, pdata, &nSize);
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
{
RAND_add(pdata, nSize, nSize/100.0);
memset(pdata, 0, nSize);
LogPrint(BCLog::LogFlags::NOISY, "rand", "RandAddSeed() %lu bytes", nSize);
}
#endif
}

uint64_t GetRand(uint64_t nMax)
{
if (nMax == 0)
Expand Down
3 changes: 0 additions & 3 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ extern bool fLogTimestamps;
extern bool fReopenDebugLog;
extern bool fDevbuildCripple;

void RandAddSeed();
void RandAddSeedPerfmon();

void LogException(std::exception* pex, const char* pszThread);
void PrintException(std::exception* pex, const char* pszThread);
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
Expand Down
3 changes: 0 additions & 3 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ CPubKey CWallet::GenerateNewKey()
AssertLockHeld(cs_wallet); // mapKeyMetadata
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets

RandAddSeedPerfmon();
CKey key;
key.MakeNewKey(fCompressed);

Expand Down Expand Up @@ -307,14 +306,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return false;

CKeyingMaterial vMasterKey;
RandAddSeedPerfmon();

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

CMasterKey kMasterKey(nDerivationMethodIndex);

RandAddSeedPerfmon();
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);

Expand Down

0 comments on commit 6df1dc5

Please sign in to comment.