Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115864
D8287.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
D8287.diff
View Options
diff --git a/src/net.cpp b/src/net.cpp
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -15,6 +15,7 @@
#include <consensus/consensus.h>
#include <crypto/sha256.h>
#include <netbase.h>
+#include <random.h>
#include <scheduler.h>
#include <ui_interface.h>
#include <util/strencodings.h>
@@ -457,6 +458,10 @@
pszDest ? pszDest : "", false, block_relay_only);
pnode->AddRef();
+ // We're making a new connection, harvest entropy from the time (and our
+ // peer count)
+ RandAddEvent((uint32_t)id);
+
return pnode;
}
@@ -721,8 +726,13 @@
msg.m_message_size = hdr.nMessageSize;
msg.m_raw_message_size = hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
+ // We just received a message off the wire, harvest entropy from the time
+ // (and the message checksum)
+ RandAddEvent(ReadLE32(hash.begin()));
+
msg.m_valid_checksum = (memcmp(hash.begin(), hdr.pchChecksum,
CMessageHeader::CHECKSUM_SIZE) == 0);
+
if (!msg.m_valid_checksum) {
LogPrint(
BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n",
@@ -1130,6 +1140,10 @@
LOCK(cs_vNodes);
vNodes.push_back(pnode);
}
+
+ // We received a new connection, harvest entropy from the time (and our peer
+ // count)
+ RandAddEvent((uint32_t)id);
}
void CConnman::DisconnectNodes() {
diff --git a/src/random.h b/src/random.h
--- a/src/random.h
+++ b/src/random.h
@@ -94,6 +94,14 @@
*/
void RandAddPeriodic() noexcept;
+/**
+ * Gathers entropy from the low bits of the time at which events occur. Should
+ * be called with a uint32_t describing the event at the time an event occurs.
+ *
+ * Thread-safe.
+ */
+void RandAddEvent(const uint32_t event_info) noexcept;
+
/**
* Fast randomness source. This is seeded once with secure random data, but
* is completely deterministic and does not gather more entropy after that.
diff --git a/src/random.cpp b/src/random.cpp
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -10,6 +10,7 @@
#include <wincrypt.h>
#endif
#include <compat/cpuid.h>
+#include <crypto/sha256.h>
#include <crypto/sha512.h>
#include <logging.h> // for LogPrintf()
#include <randomenv.h>
@@ -403,11 +404,43 @@
uint64_t m_counter GUARDED_BY(m_mutex) = 0;
bool m_strongly_seeded GUARDED_BY(m_mutex) = false;
+ Mutex m_events_mutex;
+ CSHA256 m_events_hasher GUARDED_BY(m_events_mutex);
+
public:
RNGState() noexcept { InitHardwareRand(); }
~RNGState() {}
+ void AddEvent(uint32_t event_info) noexcept {
+ LOCK(m_events_mutex);
+
+ m_events_hasher.Write((const uint8_t *)&event_info, sizeof(event_info));
+ // Get the low four bytes of the performance counter. This translates to
+ // roughly the subsecond part.
+ uint32_t perfcounter = (GetPerformanceCounter() & 0xffffffff);
+ m_events_hasher.Write((const uint8_t *)&perfcounter,
+ sizeof(perfcounter));
+ }
+
+ /**
+ * Feed (the hash of) all events added through AddEvent() to hasher.
+ */
+ void SeedEvents(CSHA512 &hasher) noexcept {
+ // We use only SHA256 for the events hashing to get the ASM speedups we
+ // have for SHA256, since we want it to be fast as network peers may be
+ // able to trigger it repeatedly.
+ LOCK(m_events_mutex);
+
+ uint8_t events_hash[32];
+ m_events_hasher.Finalize(events_hash);
+ hasher.Write(events_hash, 32);
+
+ // Re-initialize the hasher with the finalized state to use later.
+ m_events_hasher.Reset();
+ m_events_hasher.Write(events_hash, 32);
+ }
+
/**
* Extract up to 32 bytes of entropy from the RNG state, mixing in new
* entropy from hasher.
@@ -482,7 +515,7 @@
SeedTimestamp(hasher);
}
-static void SeedSlow(CSHA512 &hasher) noexcept {
+static void SeedSlow(CSHA512 &hasher, RNGState &rng) noexcept {
uint8_t buffer[32];
// Everything that the 'fast' seeder includes
@@ -492,6 +525,9 @@
GetOSRand(buffer);
hasher.Write(buffer, sizeof(buffer));
+ // Add the events hasher into the mix
+ rng.SeedEvents(hasher);
+
// High-precision timestamp.
//
// Note that we also commit to a timestamp in the Fast seeder, so we
@@ -519,6 +555,9 @@
// High-precision timestamp
SeedTimestamp(hasher);
+ // Add the events hasher into the mix
+ rng.SeedEvents(hasher);
+
// Dynamic environment data (performance monitoring, ...)
auto old_size = hasher.Size();
RandAddDynamicEnv(hasher);
@@ -535,7 +574,7 @@
SeedHardwareSlow(hasher);
// Everything that the 'slow' seeder includes.
- SeedSlow(hasher);
+ SeedSlow(hasher, rng);
// Dynamic environment data (performance monitoring, ...)
auto old_size = hasher.Size();
@@ -556,7 +595,7 @@
PERIODIC, //!< Called by RandAddPeriodic()
};
-static void ProcRand(uint8_t *out, int num, RNGLevel level) {
+static void ProcRand(uint8_t *out, int num, RNGLevel level) noexcept {
// Make sure the RNG is initialized first (as all Seed* function possibly
// need hwrand to be available).
RNGState &rng = GetRNGState();
@@ -569,7 +608,7 @@
SeedFast(hasher);
break;
case RNGLevel::SLOW:
- SeedSlow(hasher);
+ SeedSlow(hasher, rng);
break;
case RNGLevel::PERIODIC:
SeedPeriodic(hasher, rng);
@@ -595,6 +634,10 @@
ProcRand(nullptr, 0, RNGLevel::PERIODIC);
}
+void RandAddEvent(const uint32_t event_info) noexcept {
+ GetRNGState().AddEvent(event_info);
+}
+
bool g_mock_deterministic_tests{false};
uint64_t GetRand(uint64_t nMax) noexcept {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 12:21 (7 m, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187834
Default Alt Text
D8287.diff (5 KB)
Attached To
D8287: Seed RNG with precision timestamps on receipt of net messages.
Event Timeline
Log In to Comment