New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch all RNG code to the built-in PRNG #14955
Conversation
Compile failure on macOS (10.14.2):
|
Might be desirable to stick the openssl stuff behind a define already, I expect we'll be able to ship 0.18 without linking bitcoind to openssl. |
0a9f297
to
b2fbb03
Compare
@sipa I am eager to add entropy sources! (but I meant behind a ifdef that is currently on... just since I think you're touching the only remaining callsites) |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
b2fbb03
to
2390b70
Compare
75afa09
to
91367fb
Compare
Made a number of improvements, and split the history out into hopefully more self-contained commits. |
91367fb
to
2b2684d
Compare
In constructor of CTxMemPool require to call random functions, but the constructor of the mutex has not being called yet. (Maybe it is an undefined behavior or it's a bug of VC++) Line 244 in e7b88ec
|
730d6a7
to
a2a81d1
Compare
@ken2812221 That was helpful, thanks! I think I've fixed it, but the same error still appears. Can you check what line number it's on now? |
g_logger has not been newed. Line 24 in f080c65
|
@ken2812221 Thanks so much; this was an actual bug. |
6498870
to
0644236
Compare
I've made a few policy changes still:
The global-order-independent initialization now uses a function which stores the RNG state in a local static variable. C++11 guarantees that it is initialized on first call, even if called multiple times simultaneously. I've benchmarked this approach and it's even faster than using |
3b001b0
to
57788fa
Compare
This guarantees that OpenSSL is initialized properly whenever randomness is used, even when that randomness is invoked from global constructors. Note that this patch uses Mutex directly, rather than CCriticalSection. This is because the lock-detection code is not necessarily initialized during global constructors.
It includes the following policy changes: * All GetRand* functions seed the stack pointer and rdrand result (in addition to the performance counter) * The periodic entropy added by the idle scheduler now seeds stack pointer, rdrand and perfmon data (once every 10 minutes) in addition to just a sleep timing. * The entropy added when calling GetStrongRandBytes no longer includes the once-per-10-minutes perfmon data on windows (it is moved to the idle scheduler instead, where latency matters less). Other changes: * OpenSSL is no longer seeded directly anywhere. Instead, any generated randomness through our own RNG is fed back to OpenSSL (after an additional hashing step to prevent leaking our RNG state). * Seeding that was previously done directly in RandAddSeedSleep is now moved to SeedSleep(), which is indirectly invoked through ProcRand from RandAddSeedSleep. * Seeding that was previously done directly in GetStrongRandBytes() is now moved to SeedSlow(), which is indirectly invoked through ProcRand from GetStrongRandBytes().
All access to hwrand is now gated by GetRNGState, which initializes the hwrand code.
57788fa
to
223de8d
Compare
Wonderful, re-tACK 223de8d |
FWIW, I've benchmarked this before and after this PR on my system. GetRandBytes goes from around ~1 μs to ~3 μs. GetStrongRandBytes stays around ~10 μs. Note that GetRandBytes is no longer called inside tight loops since #14624. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 223de8d. All changes since last review are renames or comment improvements.
223de8d Document RNG design in random.h (Pieter Wuille) f2e60ca Use secure allocator for RNG state (Pieter Wuille) cddb31b Encapsulate RNGState better (Pieter Wuille) 152146e DRY: Implement GetRand using FastRandomContext::randrange (Pieter Wuille) a1f252e Sprinkle some sweet noexcepts over the RNG code (Pieter Wuille) 4ea8e50 Remove hwrand_initialized. (Pieter Wuille) 9d7032e Switch all RNG code to the built-in PRNG. (Pieter Wuille) 16e40a8 Integrate util/system's CInit into RNGState (Pieter Wuille) 2ccc3d3 Abstract out seeding/extracting entropy into RNGState::MixExtract (Pieter Wuille) aae8b9b Add thread safety annotations to RNG state (Pieter Wuille) d3f54d1 Rename some hardware RNG related functions (Pieter Wuille) 05fde14 Automatically initialize RNG on first use. (Pieter Wuille) 2d1cc50 Don't log RandAddSeedPerfmon details (Pieter Wuille) 6a57ca9 Use 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
cecbf6c Use secure.h header for secure allocators (Fuzzbawls) d9f67da net: add ifaddrs.h include (fanquake) e906436 build: check if -lsocket is required with *ifaddrs (fanquake) 414f405 rand: only try and use freeifaddrs if available (fanquake) 3a039d6 build: avoid getifaddrs when unavailable (Cory Fields) 77bddd7 Use GetStrongRandBytes in gmp bignum initialization (Fuzzbawls) b70b26f Fix typo in comment in randomenv.cpp (Fuzzbawls) fec460c Put bounds on the number of CPUID leaves explored (Pieter Wuille) 41ab1ff Fix CPUID subleaf iteration (Pieter Wuille) 8a9bbb1 Move events_hasher into RNGState() (Pieter Wuille) 88c2ae5 random: mark RandAddPeriodic and SeedPeriodic as noexcept (fanquake) 81d382f doc: correct random.h docs after bitcoin#17270 (fanquake) f363ea9 Seed RNG with precision timestamps on receipt of net messages. (Matt Corallo) 7d6ddcb Run background seeding periodically instead of unpredictably (Pieter Wuille) 4679181 Add information gathered through getauxval() (Pieter Wuille) 88d97d0 Feed CPUID data into RNG (Pieter Wuille) 8f5b9c9 Use sysctl for seeding on MacOS/BSD (Pieter Wuille) 67de246 Gather additional entropy from the environment (Pieter Wuille) 6142e1f Seed randomness with process id / thread id / various clocks (Pieter Wuille) 7bde8b7 [MOVEONLY] Move cpuid code from random to compat/cpuid (Fuzzbawls) 52b5336 [MOVEONLY] Move perfmon data gathering to new randomenv module (Pieter Wuille) 27cf995 doc: minor corrections in random.cpp (fanquake) fccd2b8 doc: correct function name in ReportHardwareRand() (fanquake) 909473e Fix FreeBSD build by including utilstrencodings.h (Fuzzbawls) 630931f break circular dependency: random/sync -> util -> random/sync (Fuzzbawls) 5eed08c random: remove call to RAND_screen() (Windows only) (fanquake) ada9868 gui: remove OpenSSL PRNG seeding (Windows, Qt only) (fanquake) 22a7121 Fix non-deterministic coverage of test DoS_mapOrphans (Fuzzbawls) 79e7fd3 Add ChaCha20 bench (Jonas Schnelli) 6966aa9 Add ChaCha20 encryption option (XOR) (Jonas Schnelli) 28c9cdb tests: Add script checking for deterministic line coverage (practicalswift) c82e359 test: Make bloom tests deterministic (MarcoFalke) 7b33223 Document strenghtening (Pieter Wuille) 0190dec Add hash strengthening to the RNG (Pieter Wuille) 67e336d Use RdSeed when available, and reduce RdRand load (Pieter Wuille) 4ffda1f Document RNG design in random.h (Pieter Wuille) 2b6381e Use secure allocator for RNG state (Pieter Wuille) 080deb3 Encapsulate RNGState better (Pieter Wuille) 787d72f DRY: Implement GetRand using FastRandomContext::randrange (Pieter Wuille) 5bc2583 Sprinkle some sweet noexcepts over the RNG code (Pieter Wuille) 774899f Remove hwrand_initialized. (Pieter Wuille) 698d133 Switch all RNG code to the built-in PRNG. (Pieter Wuille) 038a45a Integrate util/system's CInit into RNGState (Fuzzbawls) 5f20e62 Abstract out seeding/extracting entropy into RNGState::MixExtract (Pieter Wuille) 298f97c Add thread safety annotations to RNG state (Pieter Wuille) 2326535 Rename some hardware RNG related functions (Pieter Wuille) d76ee83 Automatically initialize RNG on first use. (Pieter Wuille) 1a5dbc5 Don't log RandAddSeedPerfmon details (Pieter Wuille) 32e6c42 Simplify testing RNG code (Fuzzbawls) 972effa Make unit tests use the insecure_rand_ctx exclusively (Fuzzbawls) af52bf5 Use a FastRandomContext in LimitOrphanTxSize (Fuzzbawls) 746d466 Introduce a Shuffle for FastRandomContext and use it in wallet (Fuzzbawls) 1cdf124 Use a local FastRandomContext in a few more places in net (Fuzzbawls) e862564 Make addrman use its local RNG exclusively (Fuzzbawls) 94b2ead Make FastRandomContext support standard C++11 RNG interface (Pieter Wuille) Pull request description: This is a collection of upstream PRs that have been backported to bring our RNG (`src/random`) code more up-to-date. The following upstream PRs have been included here: - bitcoin#12742 - bitcoin#14624 - some of this had already been merged previously - bitcoin#14955 - bitcoin#15250 - bitcoin#15224 - bitcoin#15324 - bitcoin#15296 - bitcoin#15512 - bitcoin#16878 - bitcoin#17151 - bitcoin#17191 - bitcoin#13236 - bitcoin#13314 - bitcoin#17169 - bitcoin#17270 - omitted last commit as our testing framework doesn't support it currently - omitted bitcoin@64e1e02, to be pulled in after our time utility is updated in a separate PR - bitcoin#17573 - bitcoin#17507 - bitcoin#17670 - bitcoin#17527 - bitcoin#14127 - bitcoin#21486 ACKs for top commit: furszy: ACK cecbf6c with a minor nit that can be easily tackled later. random-zebra: rebase utACK cecbf6c and merging... Tree-SHA512: 3463b693cc9bddc1ec15228d264a794f5c2f159073fafa2ccf6e2563abfeb4369e49505f97ca84f2478ca792bd07b66d2cd83c58044d6a0cae6af42d22f5784b
223de8d Document RNG design in random.h (Pieter Wuille) f2e60ca Use secure allocator for RNG state (Pieter Wuille) cddb31b Encapsulate RNGState better (Pieter Wuille) 152146e DRY: Implement GetRand using FastRandomContext::randrange (Pieter Wuille) a1f252e Sprinkle some sweet noexcepts over the RNG code (Pieter Wuille) 4ea8e50 Remove hwrand_initialized. (Pieter Wuille) 9d7032e Switch all RNG code to the built-in PRNG. (Pieter Wuille) 16e40a8 Integrate util/system's CInit into RNGState (Pieter Wuille) 2ccc3d3 Abstract out seeding/extracting entropy into RNGState::MixExtract (Pieter Wuille) aae8b9b Add thread safety annotations to RNG state (Pieter Wuille) d3f54d1 Rename some hardware RNG related functions (Pieter Wuille) 05fde14 Automatically initialize RNG on first use. (Pieter Wuille) 2d1cc50 Don't log RandAddSeedPerfmon details (Pieter Wuille) 6a57ca9 Use 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 bitcoin#14623. Tree-SHA512: 0120e19bd4ce80a509b5c180a4f29497d299ce8242e25755880851344b825bc2d64a222bc245e659562fb5463fb7c70fbfcf003616be4dc59d0ed6534f93dd20
223de8d Document RNG design in random.h (Pieter Wuille) f2e60ca Use secure allocator for RNG state (Pieter Wuille) cddb31b Encapsulate RNGState better (Pieter Wuille) 152146e DRY: Implement GetRand using FastRandomContext::randrange (Pieter Wuille) a1f252e Sprinkle some sweet noexcepts over the RNG code (Pieter Wuille) 4ea8e50 Remove hwrand_initialized. (Pieter Wuille) 9d7032e Switch all RNG code to the built-in PRNG. (Pieter Wuille) 16e40a8 Integrate util/system's CInit into RNGState (Pieter Wuille) 2ccc3d3 Abstract out seeding/extracting entropy into RNGState::MixExtract (Pieter Wuille) aae8b9b Add thread safety annotations to RNG state (Pieter Wuille) d3f54d1 Rename some hardware RNG related functions (Pieter Wuille) 05fde14 Automatically initialize RNG on first use. (Pieter Wuille) 2d1cc50 Don't log RandAddSeedPerfmon details (Pieter Wuille) 6a57ca9 Use 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 bitcoin#14623. Tree-SHA512: 0120e19bd4ce80a509b5c180a4f29497d299ce8242e25755880851344b825bc2d64a222bc245e659562fb5463fb7c70fbfcf003616be4dc59d0ed6534f93dd20 Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
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:
After this PR:
The interface of random.h is also simplified, and documentation is added.
This implements most of #14623.