Skip to content

Commit

Permalink
[MOVEONLY] Move perfmon data gathering to new randomenv module
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa authored and Fuzzbawls committed Apr 14, 2021
1 parent 27cf995 commit 52b5336
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 42 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ set(UTIL_SOURCES
./src/fs.cpp
./src/logging.cpp
./src/random.cpp
./src/randomenv.cpp
./src/rpc/protocol.cpp
./src/sync.cpp
./src/threadinterrupt.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ BITCOIN_CORE_H = \
protocol.h \
pubkey.h \
random.h \
randomenv.h \
reverselock.h \
reverse_iterate.h \
rpc/client.h \
Expand Down Expand Up @@ -538,6 +539,7 @@ libbitcoin_util_a_SOURCES = \
interfaces/handler.cpp \
logging.cpp \
random.cpp \
randomenv.cpp \
rpc/protocol.cpp \
support/cleanse.cpp \
support/lockedpool.cpp \
Expand Down
51 changes: 9 additions & 42 deletions src/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <chrono>
#include <thread>

#include "randomenv.h"

#include "allocators.h"

#ifndef WIN32
Expand Down Expand Up @@ -268,44 +270,6 @@ static void Strengthen(const unsigned char (&seed)[32], int microseconds, CSHA51
memory_cleanse(buffer, sizeof(buffer));
}

static void RandAddSeedPerfmon(CSHA512& hasher)
{
#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data

// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetTime();

std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
while (true) {
nSize = vData.size();
ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, vData.data(), &nSize);
if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
break;
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
}
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) {
hasher.Write(vData.data(), nSize);
memory_cleanse(vData.data(), nSize);
} else {
// Performance data is only a best-effort attempt at improving the
// situation when the OS randomness (and other sources) aren't
// adequate. As a result, failure to read it is isn't considered critical,
// so we don't call RandFailure().
// TODO: Add logging when the logger is made functional before global
// constructors have been invoked.
}
#endif
}

#ifndef WIN32
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
* compatible way to get cryptographic randomness on UNIX-ish platforms.
Expand Down Expand Up @@ -590,8 +554,8 @@ static void SeedSleep(CSHA512& hasher, RNGState& rng)
// High-precision timestamp after sleeping (as we commit to both the time before and after, this measures the delay)
SeedTimestamp(hasher);

// Windows performance monitor data (once every 10 minutes)
RandAddSeedPerfmon(hasher);
// Dynamic environment data (performance monitoring, ...; once every 10 minutes)
RandAddDynamicEnv(hasher);

// Strengthen every minute
SeedStrengthen(hasher, rng);
Expand All @@ -605,8 +569,11 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
// Everything that the 'slow' seeder includes.
SeedSlow(hasher);

// Windows performance monitor data.
RandAddSeedPerfmon(hasher);
// Dynamic environment data
RandAddDynamicEnv(hasher);

// Static environment data
RandAddStaticEnv(hasher);

// Strengthen
SeedStrengthen(hasher, rng);
Expand Down
69 changes: 69 additions & 0 deletions src/randomenv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "randomenv.h"

#include "crypto/sha512.h"
#include "support/cleanse.h"
#include "utiltime.h" // for GetTime()
#ifdef WIN32
#include "compat.h" // for Windows API
#endif

#include <algorithm>
#include <vector>

#include <stdint.h>

namespace {

void RandAddSeedPerfmon(CSHA512& hasher)
{
#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data

// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetTime();

std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
while (true) {
nSize = vData.size();
ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, vData.data(), &nSize);
if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
break;
vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
}
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) {
hasher.Write(vData.data(), nSize);
memory_cleanse(vData.data(), nSize);
} else {
// Performance data is only a best-effort attempt at improving the
// situation when the OS randomness (and other sources) aren't
// adequate. As a result, failure to read it is isn't considered critical,
// so we don't call RandFailure().
// TODO: Add logging when the logger is made functional before global
// constructors have been invoked.
}
#endif
}

} // namespace

void RandAddDynamicEnv(CSHA512& hasher)
{
RandAddSeedPerfmon(hasher);
}

void RandAddStaticEnv(CSHA512& hasher)
{
}
17 changes: 17 additions & 0 deletions src/randomenv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_RANDOMENV_H
#define BITCOIN_RANDOMENV_H

#include "crypto/sha512.h"

/** Gather non-cryptographic environment data that changes over time. */
void RandAddDynamicEnv(CSHA512& hasher);

/** Gather non-cryptographic environment data that does not change over time. */
void RandAddStaticEnv(CSHA512& hasher);

#endif

0 comments on commit 52b5336

Please sign in to comment.