| 137 | } |
| 138 | |
| 139 | static void RandAddSeedPerfmon() |
| 140 | { |
| 141 | RandAddSeed(); |
| 142 | |
| 143 | #ifdef WIN32 |
| 144 | // Don't need this on Linux, OpenSSL automatically uses /dev/urandom |
| 145 | // Seed with the entire set of perfmon data |
| 146 | |
| 147 | // This can take up to 2 seconds, so only do it every 10 minutes |
| 148 | static int64_t nLastPerfmon; |
| 149 | if (GetTime() < nLastPerfmon + 10 * 60) |
| 150 | return; |
| 151 | nLastPerfmon = GetTime(); |
| 152 | |
| 153 | std::vector<unsigned char> vData(250000, 0); |
| 154 | long ret = 0; |
| 155 | unsigned long nSize = 0; |
| 156 | const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data |
| 157 | while (true) { |
| 158 | nSize = vData.size(); |
| 159 | ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize); |
| 160 | if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) |
| 161 | break; |
| 162 | vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially |
| 163 | } |
| 164 | RegCloseKey(HKEY_PERFORMANCE_DATA); |
| 165 | if (ret == ERROR_SUCCESS) { |
| 166 | RAND_add(vData.data(), nSize, nSize / 100.0); |
| 167 | memory_cleanse(vData.data(), nSize); |
| 168 | LogPrint(BCLog::RAND, "%s: %lu bytes\n", __func__, nSize); |
| 169 | } else { |
| 170 | static bool warned = false; // Warn only once |
| 171 | if (!warned) { |
| 172 | LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); |
| 173 | warned = true; |
| 174 | } |
| 175 | } |
| 176 | #endif |
| 177 | } |
| 178 | |
| 179 | #ifndef WIN32 |
| 180 | /** Fallback: get 32 bytes of system entropy from /dev/urandom. The most |
no test coverage detected