Maintain state across GetStrongRandBytes calls

This commit is contained in:
Pieter Wuille 2017-05-03 03:07:53 -07:00
parent 35da2aeed7
commit 97477c537e

View file

@ -32,6 +32,8 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#include <mutex>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/rand.h> #include <openssl/rand.h>
@ -192,6 +194,10 @@ void GetRandBytes(unsigned char* buf, int num)
} }
} }
static std::mutex cs_rng_state;
static unsigned char rng_state[32] = {0};
static uint64_t rng_counter = 0;
void GetStrongRandBytes(unsigned char* out, int num) void GetStrongRandBytes(unsigned char* out, int num)
{ {
assert(num <= 32); assert(num <= 32);
@ -207,8 +213,17 @@ void GetStrongRandBytes(unsigned char* out, int num)
GetOSRand(buf); GetOSRand(buf);
hasher.Write(buf, 32); hasher.Write(buf, 32);
// Combine with and update state
{
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);
}
// Produce output // Produce output
hasher.Finalize(buf);
memcpy(out, buf, num); memcpy(out, buf, num);
memory_cleanse(buf, 64); memory_cleanse(buf, 64);
} }