mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 10:12:28 +02:00
Merge #14955: Switch all RNG code to the built-in PRNG
223de8d94dDocument RNG design in random.h (Pieter Wuille)f2e60ca985Use secure allocator for RNG state (Pieter Wuille)cddb31bb0aEncapsulate RNGState better (Pieter Wuille)152146e782DRY: Implement GetRand using FastRandomContext::randrange (Pieter Wuille)a1f252eda8Sprinkle some sweet noexcepts over the RNG code (Pieter Wuille)4ea8e50837Remove hwrand_initialized. (Pieter Wuille)9d7032e4f0Switch all RNG code to the built-in PRNG. (Pieter Wuille)16e40a8b56Integrate util/system's CInit into RNGState (Pieter Wuille)2ccc3d3aa3Abstract out seeding/extracting entropy into RNGState::MixExtract (Pieter Wuille)aae8b9bf0fAdd thread safety annotations to RNG state (Pieter Wuille)d3f54d1c82Rename some hardware RNG related functions (Pieter Wuille)05fde14e3aAutomatically initialize RNG on first use. (Pieter Wuille)2d1cc50939Don't log RandAddSeedPerfmon details (Pieter Wuille)6a57ca91daUse FRC::randbytes instead of reading >32 bytes from RNG (Pieter Wuille) Pull request description: This does not remove OpenSSL, but makes our own PRNG the 'main' one; for GetStrongRandBytes, the OpenSSL RNG is still used (indirectly, by feeding its output into our PRNG state). It includes a few policy changes (regarding what entropy is seeded when). Before this PR: * GetRand*: * OpenSSL * GetStrongRand*: * CPU cycle counter * Perfmon data (on Windows, once 10 min) * /dev/urandom (or equivalent) * rdrand (if available) * From scheduler when idle: * CPU cycle counter before and after 1ms sleep * At startup: * CPU cycle counter before and after 1ms sleep After this PR: * GetRand*: * Stack pointer (which indirectly identifies thread and some call stack information) * rdrand (if available) * CPU cycle counter * GetStrongRand*: * Stack pointer (which indirectly identifies thread and some call stack information) * rdrand (if available) * CPU cycle counter * /dev/urandom (or equivalent) * OpenSSL * CPU cycle counter again * From scheduler when idle: * Stack pointer (which indirectly identifies thread and some call stack information) * rdrand (if available) * CPU cycle counter before and after 1ms sleep * Perfmon data (on Windows, once every 10 min) * At startup: * Stack pointer (which indirectly identifies thread and some call stack information) * rdrand (if available) * CPU cycle counter * /dev/urandom (or equivalent) * OpenSSL * CPU cycle counter again * Perfmon data (on Windows, once every 10 min) The interface of random.h is also simplified, and documentation is added. This implements most of #14623. Tree-SHA512: 0120e19bd4ce80a509b5c180a4f29497d299ce8242e25755880851344b825bc2d64a222bc245e659562fb5463fb7c70fbfcf003616be4dc59d0ed6534f93dd20
This commit is contained in:
@@ -73,9 +73,6 @@
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <thread>
|
||||
|
||||
// Application startup time (used for uptime calculation)
|
||||
@@ -86,54 +83,6 @@ const char * const BITCOIN_PID_FILENAME = "bitcoind.pid";
|
||||
|
||||
ArgsManager gArgs;
|
||||
|
||||
/** Init OpenSSL library multithreading support */
|
||||
static std::unique_ptr<CCriticalSection[]> ppmutexOpenSSL;
|
||||
void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
|
||||
{
|
||||
if (mode & CRYPTO_LOCK) {
|
||||
ENTER_CRITICAL_SECTION(ppmutexOpenSSL[i]);
|
||||
} else {
|
||||
LEAVE_CRITICAL_SECTION(ppmutexOpenSSL[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton for wrapping OpenSSL setup/teardown.
|
||||
class CInit
|
||||
{
|
||||
public:
|
||||
CInit()
|
||||
{
|
||||
// Init OpenSSL library multithreading support
|
||||
ppmutexOpenSSL.reset(new CCriticalSection[CRYPTO_num_locks()]);
|
||||
CRYPTO_set_locking_callback(locking_callback);
|
||||
|
||||
// OpenSSL can optionally load a config file which lists optional loadable modules and engines.
|
||||
// We don't use them so we don't require the config. However some of our libs may call functions
|
||||
// which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
|
||||
// or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
|
||||
// that the config appears to have been loaded and there are no modules/engines available.
|
||||
OPENSSL_no_config();
|
||||
|
||||
#ifdef WIN32
|
||||
// Seed OpenSSL PRNG with current contents of the screen
|
||||
RAND_screen();
|
||||
#endif
|
||||
|
||||
// Seed OpenSSL PRNG with performance counter
|
||||
RandAddSeed();
|
||||
}
|
||||
~CInit()
|
||||
{
|
||||
// Securely erase the memory used by the PRNG
|
||||
RAND_cleanup();
|
||||
// Shutdown OpenSSL library multithreading support
|
||||
CRYPTO_set_locking_callback(nullptr);
|
||||
// Clear the set of locks now to maintain symmetry with the constructor.
|
||||
ppmutexOpenSSL.reset();
|
||||
}
|
||||
}
|
||||
instance_of_cinit;
|
||||
|
||||
/** A map that contains all the currently held directory locks. After
|
||||
* successful locking, these will be held here until the global destructor
|
||||
* cleans them up and thus automatically unlocks them, or ReleaseDirectoryLocks
|
||||
|
||||
Reference in New Issue
Block a user