| 44 | } |
| 45 | |
| 46 | void RandAddSeedPerfmon() |
| 47 | { |
| 48 | RandAddSeed(); |
| 49 | |
| 50 | #ifdef WIN32 |
| 51 | // Don't need this on Linux, OpenSSL automatically uses /dev/urandom |
| 52 | // Seed with the entire set of perfmon data |
| 53 | |
| 54 | // This can take up to 2 seconds, so only do it every 10 minutes |
| 55 | static int64_t nLastPerfmon; |
| 56 | if (GetTime() < nLastPerfmon + 10 * 60) |
| 57 | return; |
| 58 | nLastPerfmon = GetTime(); |
| 59 | |
| 60 | std::vector<unsigned char> vData(250000, 0); |
| 61 | long ret = 0; |
| 62 | unsigned long nSize = 0; |
| 63 | const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data |
| 64 | while (true) { |
| 65 | nSize = vData.size(); |
| 66 | ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize); |
| 67 | if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize) |
| 68 | break; |
| 69 | vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially |
| 70 | } |
| 71 | RegCloseKey(HKEY_PERFORMANCE_DATA); |
| 72 | if (ret == ERROR_SUCCESS) { |
| 73 | RAND_add(begin_ptr(vData), nSize, nSize / 100.0); |
| 74 | memory_cleanse(begin_ptr(vData), nSize); |
| 75 | LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); |
| 76 | } else { |
| 77 | static bool warned = false; // Warn only once |
| 78 | if (!warned) { |
| 79 | LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); |
| 80 | warned = true; |
| 81 | } |
| 82 | } |
| 83 | #endif |
| 84 | } |
| 85 | |
| 86 | void GetRandBytes(unsigned char* buf, int num) |
| 87 | { |
no test coverage detected