Skip to content

Commit 2ccc3d3

Browse files
committed
Abstract out seeding/extracting entropy into RNGState::MixExtract
1 parent aae8b9b commit 2ccc3d3

File tree

2 files changed

+37
-25
lines changed

2 files changed

+37
-25
lines changed

src/crypto/sha512.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class CSHA512
1717
uint64_t bytes;
1818

1919
public:
20-
static const size_t OUTPUT_SIZE = 64;
20+
static constexpr size_t OUTPUT_SIZE = 64;
2121

2222
CSHA512();
2323
CSHA512& Write(const unsigned char* data, size_t len);

src/random.cpp

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,34 @@ struct RNGState {
304304
{
305305
InitHardwareRand();
306306
}
307+
308+
/** Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher. */
309+
void MixExtract(unsigned char* out, size_t num, CSHA512&& hasher)
310+
{
311+
assert(num <= 32);
312+
unsigned char buf[64];
313+
static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size");
314+
{
315+
LOCK(m_mutex);
316+
// Write the current state of the RNG into the hasher
317+
hasher.Write(m_state, 32);
318+
// Write a new counter number into the state
319+
hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter));
320+
++m_counter;
321+
// Finalize the hasher
322+
hasher.Finalize(buf);
323+
// Store the last 32 bytes of the hash output as new RNG state.
324+
memcpy(m_state, buf + 32, 32);
325+
}
326+
// If desired, copy (up to) the first 32 bytes of the hash output as output.
327+
if (num) {
328+
assert(out != nullptr);
329+
memcpy(out, buf, num);
330+
}
331+
// Best effort cleanup of internal state
332+
hasher.Reset();
333+
memory_cleanse(buf, 64);
334+
}
307335
};
308336

309337
RNGState& GetRNGState()
@@ -315,38 +343,29 @@ RNGState& GetRNGState()
315343
}
316344
}
317345

318-
static void AddDataToRng(void* data, size_t len);
346+
static void AddDataToRng(void* data, size_t len, RNGState& rng);
319347

320348
void RandAddSeedSleep()
321349
{
350+
RNGState& rng = GetRNGState();
351+
322352
int64_t nPerfCounter1 = GetPerformanceCounter();
323353
std::this_thread::sleep_for(std::chrono::milliseconds(1));
324354
int64_t nPerfCounter2 = GetPerformanceCounter();
325355

326356
// Combine with and update state
327-
AddDataToRng(&nPerfCounter1, sizeof(nPerfCounter1));
328-
AddDataToRng(&nPerfCounter2, sizeof(nPerfCounter2));
357+
AddDataToRng(&nPerfCounter1, sizeof(nPerfCounter1), rng);
358+
AddDataToRng(&nPerfCounter2, sizeof(nPerfCounter2), rng);
329359

330360
memory_cleanse(&nPerfCounter1, sizeof(nPerfCounter1));
331361
memory_cleanse(&nPerfCounter2, sizeof(nPerfCounter2));
332362
}
333363

334-
static void AddDataToRng(void* data, size_t len) {
335-
RNGState& rng = GetRNGState();
336-
364+
static void AddDataToRng(void* data, size_t len, RNGState& rng) {
337365
CSHA512 hasher;
338366
hasher.Write((const unsigned char*)&len, sizeof(len));
339367
hasher.Write((const unsigned char*)data, len);
340-
unsigned char buf[64];
341-
{
342-
WAIT_LOCK(rng.m_mutex, lock);
343-
hasher.Write(rng.m_state, sizeof(rng.m_state));
344-
hasher.Write((const unsigned char*)&rng.m_counter, sizeof(rng.m_counter));
345-
++rng.m_counter;
346-
hasher.Finalize(buf);
347-
memcpy(rng.m_state, buf + 32, 32);
348-
}
349-
memory_cleanse(buf, 64);
368+
rng.MixExtract(nullptr, 0, std::move(hasher));
350369
}
351370

352371
void GetStrongRandBytes(unsigned char* out, int num)
@@ -372,14 +391,7 @@ void GetStrongRandBytes(unsigned char* out, int num)
372391
}
373392

374393
// Combine with and update state
375-
{
376-
WAIT_LOCK(rng.m_mutex, lock);
377-
hasher.Write(rng.m_state, sizeof(rng.m_state));
378-
hasher.Write((const unsigned char*)&rng.m_counter, sizeof(rng.m_counter));
379-
++rng.m_counter;
380-
hasher.Finalize(buf);
381-
memcpy(rng.m_state, buf + 32, 32);
382-
}
394+
rng.MixExtract(out, num, std::move(hasher));
383395

384396
// Produce output
385397
memcpy(out, buf, num);

0 commit comments

Comments
 (0)