// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include // for GetTime() #ifdef WIN32 #include // for Windows API #endif #include #include #include namespace { void RandAddSeedPerfmon(CSHA512& hasher) { #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 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", nullptr, nullptr, vData.data(), &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) { hasher.Write(vData.data(), nSize); memory_cleanse(vData.data(), nSize); } else { // Performance data is only a best-effort attempt at improving the // situation when the OS randomness (and other sources) aren't // adequate. As a result, failure to read it is isn't considered critical, // so we don't call RandFailure(). // TODO: Add logging when the logger is made functional before global // constructors have been invoked. } #endif } } // namespace void RandAddDynamicEnv(CSHA512& hasher) { RandAddSeedPerfmon(hasher); } void RandAddStaticEnv(CSHA512& hasher) { }