Skip to content

Commit c117d6b

Browse files
TheBlueMattFuzzbawls
authored andcommitted
Seed RNG with precision timestamps on receipt of net messages.
1 parent 2e92e8d commit c117d6b

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/net.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "netbase.h"
2222
#include "netmessagemaker.h"
2323
#include "primitives/transaction.h"
24+
#include "random.h"
2425
#include "scheduler.h"
2526
#include "validation.h"
2627

@@ -379,6 +380,9 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char* pszDest, bool fCo
379380
pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
380381
pnode->AddRef();
381382

383+
// We're making a new connection, harvest entropy from the time (and our peer count)
384+
RandAddEvent((uint32_t)id);
385+
382386
return pnode;
383387
} else if (!proxyConnectionFailed) {
384388
// If connecting to the node failed, and failure is not caused by a problem connecting to
@@ -1067,6 +1071,9 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
10671071
LOCK(cs_vNodes);
10681072
vNodes.push_back(pnode);
10691073
}
1074+
1075+
// We received a new connection, harvest entropy from the time (and our peer count)
1076+
RandAddEvent((uint32_t)id);
10701077
}
10711078

10721079
void CConnman::ThreadSocketHandler()

src/random.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "random.h"
88

99
#include "compat/cpuid.h"
10+
#include "crypto/sha256.h"
1011
#include "crypto/sha512.h"
1112
#include "support/cleanse.h"
1213
#ifdef WIN32
@@ -489,6 +490,23 @@ static void SeedFast(CSHA512& hasher) noexcept
489490
SeedTimestamp(hasher);
490491
}
491492

493+
// We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
494+
// since we want it to be fast as network peers may be able to trigger it repeatedly.
495+
static Mutex events_mutex;
496+
static CSHA256 events_hasher;
497+
static void SeedEvents(CSHA512& hasher)
498+
{
499+
LOCK(events_mutex);
500+
501+
unsigned char events_hash[32];
502+
events_hasher.Finalize(events_hash);
503+
hasher.Write(events_hash, 32);
504+
505+
// Re-initialize the hasher with the finalized state to use later.
506+
events_hasher.Reset();
507+
events_hasher.Write(events_hash, 32);
508+
}
509+
492510
static void SeedSlow(CSHA512& hasher) noexcept
493511
{
494512
unsigned char buffer[32];
@@ -504,6 +522,9 @@ static void SeedSlow(CSHA512& hasher) noexcept
504522
RAND_bytes(buffer, sizeof(buffer));
505523
hasher.Write(buffer, sizeof(buffer));
506524

525+
// Add the events hasher into the mix
526+
SeedEvents(hasher);
527+
507528
// High-precision timestamp.
508529
//
509530
// Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a
@@ -529,6 +550,9 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng)
529550
// High-precision timestamp
530551
SeedTimestamp(hasher);
531552

553+
// Add the events hasher into the mix
554+
SeedEvents(hasher);
555+
532556
// Dynamic environment data (performance monitoring, ...)
533557
RandAddDynamicEnv(hasher);
534558

@@ -601,6 +625,15 @@ void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNG
601625
void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); }
602626
void RandAddPeriodic() { ProcRand(nullptr, 0, RNGLevel::PERIODIC); }
603627

628+
void RandAddEvent(const uint32_t event_info) {
629+
LOCK(events_mutex);
630+
events_hasher.Write((const unsigned char *)&event_info, sizeof(event_info));
631+
// Get the low four bytes of the performance counter. This translates to roughly the
632+
// subsecond part.
633+
uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
634+
events_hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter));
635+
}
636+
604637
bool g_mock_deterministic_tests{false};
605638

606639
uint64_t GetRand(uint64_t nMax) noexcept

src/random.h

+8
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ void GetStrongRandBytes(unsigned char* buf, int num) noexcept;
8989
*/
9090
void RandAddPeriodic();
9191

92+
/**
93+
* Gathers entropy from the low bits of the time at which events occur. Should
94+
* be called with a uint32_t describing the event at the time an event occurs.
95+
*
96+
* Thread-safe.
97+
*/
98+
void RandAddEvent(const uint32_t event_info);
99+
92100
/**
93101
* Fast randomness source. This is seeded once with secure random data, but
94102
* is completely deterministic and does not gather more entropy after that.

0 commit comments

Comments
 (0)