diff --git a/src/Makefile.am b/src/Makefile.am index 9b0b97b7a..90e0a43be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,6 +91,7 @@ BITCOIN_CORE_H = \ noui.h \ pow.h \ protocol.h \ + random.h \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ @@ -197,14 +198,15 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ chainparamsbase.cpp \ + random.cpp \ rpcprotocol.cpp \ sync.cpp \ uint256.cpp \ util.cpp \ version.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ $(BITCOIN_CORE_H) if GLIBC_BACK_COMPAT diff --git a/src/addrman.h b/src/addrman.h index c4c296560..a0dc134c4 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -7,6 +7,7 @@ #include "netbase.h" #include "protocol.h" +#include "random.h" #include "sync.h" #include "timedata.h" #include "util.h" @@ -16,8 +17,6 @@ #include #include -#include - /** Extended statistics about a CAddress */ class CAddrInfo : public CAddress { @@ -384,7 +383,7 @@ public: CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set()) { nKey.resize(32); - RAND_bytes(&nKey[0], 32); + GetRandBytes(&nKey[0], 32); nIdCount = 0; nTried = 0; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b9097ea96..fb1d05f83 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -6,6 +6,7 @@ #include "chainparams.h" #include "assert.h" +#include "random.h" #include "util.h" #include diff --git a/src/key.cpp b/src/key.cpp index 3c4fa77e7..a253f8666 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,11 +1,11 @@ -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" #include "crypto/sha2.h" -#include +#include "random.h" #ifdef USE_SECP256K1 #include @@ -194,7 +194,7 @@ public: if (d2i_ECPrivateKey(&pkey, &pbegin, privkey.size())) { if(fSkipCheck) return true; - + // d2i_ECPrivateKey returns true if parsing succeeds. // This doesn't necessarily mean the key is valid. if (EC_KEY_check_key(pkey)) @@ -412,7 +412,7 @@ bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) { void CKey::MakeNewKey(bool fCompressedIn) { do { - RAND_bytes(vch, sizeof(vch)); + GetRandBytes(vch, sizeof(vch)); } while (!Check(vch)); fValid = true; fCompressed = fCompressedIn; @@ -745,5 +745,3 @@ bool ECC_InitSanityCheck() { return true; #endif } - - diff --git a/src/main.cpp b/src/main.cpp index c5a3b284e..4f6b442f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4381,7 +4381,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pingSend) { uint64_t nonce = 0; while (nonce == 0) { - RAND_bytes((unsigned char*)&nonce, sizeof(nonce)); + GetRandBytes((unsigned char*)&nonce, sizeof(nonce)); } pto->fPingQueued = false; pto->nPingUsecStart = GetTimeMicros(); diff --git a/src/net.cpp b/src/net.cpp index 6a6d9df6a..3b3d91d65 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -555,7 +555,7 @@ void CNode::PushVersion() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); CAddress addrMe = GetLocalAddress(&addr); - RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); if (fLogIPs) LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else @@ -1961,7 +1961,7 @@ bool CAddrDB::Write(const CAddrMan& addr) { // Generate random temporary filename unsigned short randv = 0; - RAND_bytes((unsigned char *)&randv, sizeof(randv)); + GetRandBytes((unsigned char*)&randv, sizeof(randv)); std::string tmpfn = strprintf("peers.dat.%04x", randv); // serialize addresses, checksum data up to that point, then append csum diff --git a/src/net.h b/src/net.h index 4e42a1eeb..866c9ae78 100644 --- a/src/net.h +++ b/src/net.h @@ -13,6 +13,7 @@ #include "mruset.h" #include "netbase.h" #include "protocol.h" +#include "random.h" #include "sync.h" #include "uint256.h" #include "util.h" @@ -26,7 +27,6 @@ #include #include -#include class CAddrMan; class CBlockIndex; diff --git a/src/random.cpp b/src/random.cpp new file mode 100644 index 000000000..0d20d205a --- /dev/null +++ b/src/random.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "random.h" + +#ifdef WIN32 +#include "compat.h" // for Windows API +#endif +#include "util.h" // for LogPrint() + +#ifndef WIN32 +#include +#endif + +#include +#include +#include + +static inline int64_t GetPerformanceCounter() +{ + int64_t nCounter = 0; +#ifdef WIN32 + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + timeval t; + gettimeofday(&t, NULL); + nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec); +#endif + return nCounter; +} + +void RandAddSeed() +{ + // Seed with CPU performance counter + int64_t nCounter = GetPerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter)); +} + +void RandAddSeedPerfmon() +{ + RandAddSeed(); + + // 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(); + +#ifdef WIN32 + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom + // Seed with the entire set of perfmon data + std::vector 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); + OPENSSL_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 +} + +bool 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)); + return false; + } + return true; +} + +uint64_t GetRand(uint64_t nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64_t nRange = (std::numeric_limits::max() / nMax) * nMax; + uint64_t nRand = 0; + do { + GetRandBytes((unsigned char*)&nRand, sizeof(nRand)); + } while (nRand >= nRange); + return (nRand % nMax); +} + +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} + +uint256 GetRandHash() +{ + uint256 hash; + GetRandBytes((unsigned char*)&hash, sizeof(hash)); + return hash; +} + +uint32_t insecure_rand_Rz = 11; +uint32_t insecure_rand_Rw = 11; +void seed_insecure_rand(bool fDeterministic) +{ + // The seed values have some unlikely fixed points which we avoid. + if(fDeterministic) + { + insecure_rand_Rz = insecure_rand_Rw = 11; + } else { + uint32_t tmp; + do { + GetRandBytes((unsigned char*)&tmp, 4); + } while(tmp == 0 || tmp == 0x9068ffffU); + insecure_rand_Rz = tmp; + do { + GetRandBytes((unsigned char*)&tmp, 4); + } while(tmp == 0 || tmp == 0x464fffffU); + insecure_rand_Rw = tmp; + } +} diff --git a/src/random.h b/src/random.h new file mode 100644 index 000000000..a599b0847 --- /dev/null +++ b/src/random.h @@ -0,0 +1,49 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RANDOM_H +#define BITCOIN_RANDOM_H + +#include "uint256.h" + +#include + +/** + * Seed OpenSSL PRNG with additional entropy data + */ +void RandAddSeed(); +void RandAddSeedPerfmon(); + +/** + * Functions to gather random data via the OpenSSL PRNG + */ +bool GetRandBytes(unsigned char *buf, int num); +uint64_t GetRand(uint64_t nMax); +int GetRandInt(int nMax); +uint256 GetRandHash(); + +/** + * Seed insecure_rand using the random pool. + * @param Deterministic Use a determinstic seed + */ +void seed_insecure_rand(bool fDeterministic = false); + +/** + * MWC RNG of George Marsaglia + * This is intended to be fast. It has a period of 2^59.3, though the + * least significant 16 bits only have a period of about 2^30.1. + * + * @return random value + */ +extern uint32_t insecure_rand_Rz; +extern uint32_t insecure_rand_Rw; +static inline uint32_t insecure_rand(void) +{ + insecure_rand_Rz = 36969 * (insecure_rand_Rz & 65535) + (insecure_rand_Rz >> 16); + insecure_rand_Rw = 18000 * (insecure_rand_Rw & 65535) + (insecure_rand_Rw >> 16); + return (insecure_rand_Rw << 16) + insecure_rand_Rz; +} + +#endif // BITCOIN_RANDOM_H diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 7d7e03d96..5deb6a4e0 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -532,7 +532,7 @@ void StartRPCThreads() (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword()) { unsigned char rand_pwd[32]; - RAND_bytes(rand_pwd, 32); + GetRandBytes(rand_pwd, 32); string strWhatAmI = "To use bitcoind"; if (mapArgs.count("-server")) strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); diff --git a/src/script.cpp b/src/script.cpp index 238a25e72..39ae001db 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -5,13 +5,14 @@ #include "script.h" +#include "crypto/ripemd160.h" +#include "crypto/sha1.h" +#include "crypto/sha2.h" #include "core.h" #include "hash.h" #include "key.h" #include "keystore.h" -#include "crypto/sha1.h" -#include "crypto/sha2.h" -#include "crypto/ripemd160.h" +#include "random.h" #include "sync.h" #include "uint256.h" #include "util.h" @@ -1097,7 +1098,6 @@ uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsig // Valid signature cache, to avoid doing expensive ECDSA signature checking // twice for every transaction (once when accepted into memory pool, and // again when accepted into the block chain) - class CSignatureCache { private: diff --git a/src/test/canonical_tests.cpp b/src/test/canonical_tests.cpp index 23dd74296..a9798623e 100644 --- a/src/test/canonical_tests.cpp +++ b/src/test/canonical_tests.cpp @@ -6,12 +6,11 @@ // Unit tests for canonical signatures // - - -#include "script.h" -#include "util.h" #include "data/sig_noncanonical.json.h" #include "data/sig_canonical.json.h" +#include "random.h" +#include "script.h" +#include "util.h" #include #include @@ -21,7 +20,6 @@ using namespace std; using namespace json_spirit; - // In script_tests.cpp extern Array read_json(const std::string& jsondata); diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 7bd98fa38..a17278b80 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -5,6 +5,7 @@ #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha2.h" +#include "random.h" #include "util.h" #include diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 60f11c147..547cd1090 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -4,6 +4,7 @@ #include "mruset.h" +#include "random.h" #include "util.h" #include diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 423ae4a78..b99797fcc 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,15 +2,16 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include +#include "data/sighash.json.h" +#include "main.h" +#include "random.h" +#include "serialize.h" +#include "util.h" +#include "version.h" + #include -#include "main.h" -#include "util.h" -#include "serialize.h" -#include "version.h" -#include "data/sighash.json.h" - +#include #include "json/json_spirit_reader_template.h" #include "json/json_spirit_utils.h" #include "json/json_spirit_writer_template.h" @@ -118,7 +119,7 @@ BOOST_AUTO_TEST_SUITE(sighash_tests) BOOST_AUTO_TEST_CASE(sighash_test) { seed_insecure_rand(false); - + #if defined(PRINT_SIGHASH_JSON) std::cout << "[\n"; std::cout << "\t[\"raw_transaction, script, input_index, hashType, signature_hash (result)\"],\n"; @@ -205,10 +206,9 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); continue; } - + sh = SignatureHash(scriptCode, tx, nIn, nHashType); BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); } } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 11762c6ea..a123f1d19 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -2,11 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include #include "main.h" +#include "random.h" #include "util.h" +#include + +#include #define SKIPLIST_LENGTH 300000 @@ -98,4 +100,3 @@ BOOST_AUTO_TEST_CASE(getlocator_test) } BOOST_AUTO_TEST_SUITE_END() - diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index bcd2f75f5..443b5853b 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -4,9 +4,8 @@ #define BOOST_TEST_MODULE Bitcoin Test Suite - - #include "main.h" +#include "random.h" #include "txdb.h" #include "ui_interface.h" #include "util.h" @@ -89,4 +88,3 @@ bool ShutdownRequested() { return false; } - diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 0b071361d..068b9f29c 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -4,6 +4,7 @@ #include "util.h" +#include "random.h" #include "sync.h" #include diff --git a/src/util.cpp b/src/util.cpp index 91ac8833d..ce31619ec 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6,6 +6,7 @@ #include "util.h" #include "chainparamsbase.h" +#include "random.h" #include "sync.h" #include "uint256.h" #include "version.h" @@ -141,90 +142,6 @@ public: } 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 (GetTime() < nLastPerfmon + 10 * 60) - return; - nLastPerfmon = GetTime(); - -#ifdef WIN32 - // Don't need this on Linux, OpenSSL automatically uses /dev/urandom - // Seed with the entire set of perfmon data - std::vector 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); - OPENSSL_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 -} - -uint64_t GetRand(uint64_t nMax) -{ - if (nMax == 0) - return 0; - - // The range of the random source must be a multiple of the modulus - // to give every possible output value an equal possibility - uint64_t nRange = (std::numeric_limits::max() / nMax) * nMax; - uint64_t nRand = 0; - do - RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); - while (nRand >= nRange); - return (nRand % nMax); -} - -int GetRandInt(int nMax) -{ - return GetRand(nMax); -} - -uint256 GetRandHash() -{ - uint256 hash; - RAND_bytes((unsigned char*)&hash, sizeof(hash)); - return hash; -} - // LogPrintf() has been broken a couple of times now // by well-meaning people adding mutexes in the most straightforward way. // It breaks because it may be called by global destructors during shutdown. @@ -1192,27 +1109,6 @@ void SetMockTime(int64_t nMockTimeIn) nMockTime = nMockTimeIn; } -uint32_t insecure_rand_Rz = 11; -uint32_t insecure_rand_Rw = 11; -void seed_insecure_rand(bool fDeterministic) -{ - //The seed values have some unlikely fixed points which we avoid. - if(fDeterministic) - { - insecure_rand_Rz = insecure_rand_Rw = 11; - } else { - uint32_t tmp; - do { - RAND_bytes((unsigned char*)&tmp, 4); - } while(tmp == 0 || tmp == 0x9068ffffU); - insecure_rand_Rz = tmp; - do { - RAND_bytes((unsigned char*)&tmp, 4); - } while(tmp == 0 || tmp == 0x464fffffU); - insecure_rand_Rw = tmp; - } -} - string FormatVersion(int nVersion) { if (nVersion%100 == 0) diff --git a/src/util.h b/src/util.h index 60db71bfd..db2005337 100644 --- a/src/util.h +++ b/src/util.h @@ -90,8 +90,6 @@ inline void MilliSleep(int64_t n) #endif } - - extern std::map mapArgs; extern std::map > mapMultiArgs; extern bool fDebug; @@ -103,8 +101,6 @@ extern bool fLogTimestamps; extern bool fLogIPs; extern volatile bool fReopenDebugLog; -void RandAddSeed(); -void RandAddSeedPerfmon(); void SetupEnvironment(); /* Return true if log accepts specified category */ @@ -187,23 +183,12 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif boost::filesystem::path GetTempPath(); void ShrinkDebugFile(); -int GetRandInt(int nMax); -uint64_t GetRand(uint64_t nMax); -uint256 GetRandHash(); int64_t GetTime(); void SetMockTime(int64_t nMockTimeIn); std::string FormatFullVersion(); std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); void runCommand(std::string strCommand); - - - - - - - - inline std::string i64tostr(int64_t n) { return strprintf("%d", n); @@ -289,19 +274,6 @@ inline std::string HexStr(const T& vch, bool fSpaces=false) */ std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0); -inline int64_t GetPerformanceCounter() -{ - int64_t nCounter = 0; -#ifdef WIN32 - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); -#else - timeval t; - gettimeofday(&t, NULL); - nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec; -#endif - return nCounter; -} - inline int64_t GetTimeMillis() { return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) - @@ -370,28 +342,6 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue); */ bool SoftSetBoolArg(const std::string& strArg, bool fValue); -/** - * MWC RNG of George Marsaglia - * This is intended to be fast. It has a period of 2^59.3, though the - * least significant 16 bits only have a period of about 2^30.1. - * - * @return random value - */ -extern uint32_t insecure_rand_Rz; -extern uint32_t insecure_rand_Rw; -static inline uint32_t insecure_rand(void) -{ - insecure_rand_Rz = 36969 * (insecure_rand_Rz & 65535) + (insecure_rand_Rz >> 16); - insecure_rand_Rw = 18000 * (insecure_rand_Rw & 65535) + (insecure_rand_Rw >> 16); - return (insecure_rand_Rw << 16) + insecure_rand_Rz; -} - -/** - * Seed insecure_rand using the random pool. - * @param Deterministic Use a determinstic seed - */ -void seed_insecure_rand(bool fDeterministic=false); - /** * Timing-attack-resistant comparison. * Takes time proportional to length diff --git a/src/wallet.cpp b/src/wallet.cpp index 560cbc10b..8d27da9d4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -12,7 +12,6 @@ #include "timedata.h" #include -#include using namespace std; @@ -384,13 +383,15 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) RandAddSeedPerfmon(); vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); - RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + if (!GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE)) + return false; CMasterKey kMasterKey; - RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); - RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + if (!GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE)) + return false; CCrypter crypter; int64_t nStartTime = GetTimeMillis();