Merge #10372: Add perf counter data to GetStrongRandBytes state in scheduler

888cce5 Add perf counter data to GetStrongRandBytes state in scheduler (Matt Corallo)
399fb8f Add internal method to add new random data to our internal RNG state (Matt Corallo)

Tree-SHA512: 9732a3804d015eaf48d56b60c73880014845fd17a098f1ac2eff6bd50a4beb8b8be65956ac1f0d641e96e3a53c17daddd919401edbf2e3797c3fb687730fb913
This commit is contained in:
Wladimir J. van der Laan 2017-05-23 17:53:00 +02:00
commit 15254e907e
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
3 changed files with 46 additions and 0 deletions

View File

@ -203,10 +203,43 @@ void GetRandBytes(unsigned char* buf, int num)
}
}
static void AddDataToRng(void* data, size_t len);
void RandAddSeedSleep()
{
int64_t nPerfCounter1 = GetPerformanceCounter();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
int64_t nPerfCounter2 = GetPerformanceCounter();
// Combine with and update state
AddDataToRng(&nPerfCounter1, sizeof(nPerfCounter1));
AddDataToRng(&nPerfCounter2, sizeof(nPerfCounter2));
memory_cleanse(&nPerfCounter1, sizeof(nPerfCounter1));
memory_cleanse(&nPerfCounter2, sizeof(nPerfCounter2));
}
static std::mutex cs_rng_state;
static unsigned char rng_state[32] = {0};
static uint64_t rng_counter = 0;
static void AddDataToRng(void* data, size_t len) {
CSHA512 hasher;
hasher.Write((const unsigned char*)&len, sizeof(len));
hasher.Write((const unsigned char*)data, len);
unsigned char buf[64];
{
std::unique_lock<std::mutex> lock(cs_rng_state);
hasher.Write(rng_state, sizeof(rng_state));
hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
++rng_counter;
hasher.Finalize(buf);
memcpy(rng_state, buf + 32, 32);
}
memory_cleanse(buf, 64);
}
void GetStrongRandBytes(unsigned char* out, int num)
{
assert(num <= 32);

View File

@ -23,6 +23,13 @@ uint64_t GetRand(uint64_t nMax);
int GetRandInt(int nMax);
uint256 GetRandHash();
/**
* Add a little bit of randomness to the output of GetStrongRangBytes.
* This sleeps for a millisecond, so should only be called when there is
* no other work to be done.
*/
void RandAddSeedSleep();
/**
* Function to gather random data from multiple sources, failing whenever any
* of those source fail to provide a result.

View File

@ -4,6 +4,7 @@
#include "scheduler.h"
#include "random.h"
#include "reverselock.h"
#include <assert.h>
@ -39,6 +40,11 @@ void CScheduler::serviceQueue()
// is called.
while (!shouldStop()) {
try {
if (!shouldStop() && taskQueue.empty()) {
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
// Use this chance to get a tiny bit more entropy
RandAddSeedSleep();
}
while (!shouldStop() && taskQueue.empty()) {
// Wait until there is something to do.
newTaskScheduled.wait(lock);