Auto merge of #1706 - paragonie:master, r=bitcartel
Use libsodium's CSPRNG instead of OpenSSL's Closes #1632.
This commit is contained in:
commit
499e34fc64
|
@ -15,8 +15,8 @@ zcash_GenerateParams_LDADD = \
|
||||||
zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp
|
zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp
|
||||||
zcash_CreateJoinSplit_LDADD = \
|
zcash_CreateJoinSplit_LDADD = \
|
||||||
$(LIBBITCOIN_COMMON) \
|
$(LIBBITCOIN_COMMON) \
|
||||||
|
$(LIBZCASH) \
|
||||||
$(LIBBITCOIN_UTIL) \
|
$(LIBBITCOIN_UTIL) \
|
||||||
$(LIBBITCOIN_CRYPTO) \
|
$(LIBBITCOIN_CRYPTO) \
|
||||||
$(LIBZCASH) \
|
|
||||||
$(BOOST_LIBS) \
|
$(BOOST_LIBS) \
|
||||||
$(LIBZCASH_LIBS)
|
$(LIBZCASH_LIBS)
|
||||||
|
|
|
@ -1363,8 +1363,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
if (fFirstRun)
|
if (fFirstRun)
|
||||||
{
|
{
|
||||||
// Create new keyUser and set as default key
|
// Create new keyUser and set as default key
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
CPubKey newDefaultKey;
|
CPubKey newDefaultKey;
|
||||||
if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
|
if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
|
||||||
pwalletMain->SetDefaultKey(newDefaultKey);
|
pwalletMain->SetDefaultKey(newDefaultKey);
|
||||||
|
@ -1481,8 +1479,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
if (!strErrors.str().empty())
|
if (!strErrors.str().empty())
|
||||||
return InitError(strErrors.str());
|
return InitError(strErrors.str());
|
||||||
|
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
//// debug print
|
//// debug print
|
||||||
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
||||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||||
|
|
|
@ -21,7 +21,6 @@ bool CKey::Check(const unsigned char *vch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKey::MakeNewKey(bool fCompressedIn) {
|
void CKey::MakeNewKey(bool fCompressedIn) {
|
||||||
RandAddSeedPerfmon();
|
|
||||||
do {
|
do {
|
||||||
GetRandBytes(vch, sizeof(vch));
|
GetRandBytes(vch, sizeof(vch));
|
||||||
} while (!Check(vch));
|
} while (!Check(vch));
|
||||||
|
|
|
@ -4303,7 +4303,6 @@ void static ProcessGetData(CNode* pfrom)
|
||||||
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
|
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
|
||||||
{
|
{
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
RandAddSeedPerfmon();
|
|
||||||
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
|
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
|
||||||
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
|
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
|
|
||||||
// If we don't want a message to be processed by Qt, return true and set result to
|
// If we don't want a message to be processed by Qt, return true and set result to
|
||||||
// the value that the window procedure should return. Otherwise return false.
|
// the value that the window procedure should return. Otherwise return false.
|
||||||
bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
|
bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
|
||||||
|
@ -22,16 +20,6 @@ bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pM
|
||||||
|
|
||||||
MSG *pMsg = static_cast<MSG *>(pMessage);
|
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) {
|
|
||||||
LogPrint("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__);
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(pMsg->message)
|
switch(pMsg->message)
|
||||||
{
|
{
|
||||||
case WM_QUERYENDSESSION:
|
case WM_QUERYENDSESSION:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openssl/err.h>
|
#include "sodium.h"
|
||||||
#include <openssl/rand.h>
|
|
||||||
|
|
||||||
static inline int64_t GetPerformanceCounter()
|
static inline int64_t GetPerformanceCounter()
|
||||||
{
|
{
|
||||||
|
@ -35,60 +34,9 @@ static inline int64_t GetPerformanceCounter()
|
||||||
return nCounter;
|
return nCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RandAddSeed()
|
void GetRandBytes(unsigned char* buf, size_t num)
|
||||||
{
|
{
|
||||||
// Seed with CPU performance counter
|
randombytes_buf(buf, num);
|
||||||
int64_t nCounter = GetPerformanceCounter();
|
|
||||||
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
|
||||||
memory_cleanse((void*)&nCounter, sizeof(nCounter));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RandAddSeedPerfmon()
|
|
||||||
{
|
|
||||||
RandAddSeed();
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
|
|
||||||
// Seed with the entire set of perfmon data
|
|
||||||
|
|
||||||
// This can take up to 2 seconds, so only do it every 10 minutes
|
|
||||||
static int64_t nLastPerfmon;
|
|
||||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
|
||||||
return;
|
|
||||||
nLastPerfmon = GetTime();
|
|
||||||
|
|
||||||
std::vector<unsigned char> vData(250000, 0);
|
|
||||||
long ret = 0;
|
|
||||||
unsigned long nSize = 0;
|
|
||||||
const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
|
|
||||||
while (true) {
|
|
||||||
nSize = vData.size();
|
|
||||||
ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
|
|
||||||
if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
|
|
||||||
break;
|
|
||||||
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
|
|
||||||
}
|
|
||||||
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
|
||||||
if (ret == ERROR_SUCCESS) {
|
|
||||||
RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
|
|
||||||
memory_cleanse(begin_ptr(vData), nSize);
|
|
||||||
LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
|
|
||||||
} else {
|
|
||||||
static bool warned = false; // Warn only once
|
|
||||||
if (!warned) {
|
|
||||||
LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t GetRand(uint64_t nMax)
|
uint64_t GetRand(uint64_t nMax)
|
||||||
|
|
10
src/random.h
10
src/random.h
|
@ -12,15 +12,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seed OpenSSL PRNG with additional entropy data
|
* Functions to gather random data via the libsodium CSPRNG
|
||||||
*/
|
*/
|
||||||
void RandAddSeed();
|
void GetRandBytes(unsigned char* buf, size_t num);
|
||||||
void RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions to gather random data via the OpenSSL PRNG
|
|
||||||
*/
|
|
||||||
void GetRandBytes(unsigned char* buf, int num);
|
|
||||||
uint64_t GetRand(uint64_t nMax);
|
uint64_t GetRand(uint64_t nMax);
|
||||||
int GetRandInt(int nMax);
|
int GetRandInt(int nMax);
|
||||||
uint256 GetRandHash();
|
uint256 GetRandHash();
|
||||||
|
|
11
src/util.cpp
11
src/util.cpp
|
@ -82,7 +82,6 @@
|
||||||
#include <boost/program_options/parsers.hpp>
|
#include <boost/program_options/parsers.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
|
|
||||||
// Work around clang compilation problem in Boost 1.46:
|
// Work around clang compilation problem in Boost 1.46:
|
||||||
|
@ -142,19 +141,9 @@ public:
|
||||||
// or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
|
// or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
|
||||||
// that the config appears to have been loaded and there are no modules/engines available.
|
// that the config appears to have been loaded and there are no modules/engines available.
|
||||||
OPENSSL_no_config();
|
OPENSSL_no_config();
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// Seed OpenSSL PRNG with current contents of the screen
|
|
||||||
RAND_screen();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Seed OpenSSL PRNG with performance counter
|
|
||||||
RandAddSeed();
|
|
||||||
}
|
}
|
||||||
~CInit()
|
~CInit()
|
||||||
{
|
{
|
||||||
// Securely erase the memory used by the PRNG
|
|
||||||
RAND_cleanup();
|
|
||||||
// Shutdown OpenSSL library multithreading support
|
// Shutdown OpenSSL library multithreading support
|
||||||
CRYPTO_set_locking_callback(NULL);
|
CRYPTO_set_locking_callback(NULL);
|
||||||
for (int i = 0; i < CRYPTO_num_locks(); i++)
|
for (int i = 0; i < CRYPTO_num_locks(); i++)
|
||||||
|
|
|
@ -814,13 +814,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CKeyingMaterial vMasterKey;
|
CKeyingMaterial vMasterKey;
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
|
vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
|
||||||
GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
|
GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
|
||||||
|
|
||||||
CMasterKey kMasterKey;
|
CMasterKey kMasterKey;
|
||||||
RandAddSeedPerfmon();
|
|
||||||
|
|
||||||
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
|
kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
|
||||||
GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
|
GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
|
||||||
|
|
Loading…
Reference in New Issue