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:
commit
15254e907e
3 changed files with 46 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue