diff options
Diffstat (limited to 'src/lib/rng')
-rw-r--r-- | src/lib/rng/auto_rng/auto_rng.h | 7 | ||||
-rw-r--r-- | src/lib/rng/hmac_drbg/hmac_drbg.cpp | 10 | ||||
-rw-r--r-- | src/lib/rng/hmac_drbg/hmac_drbg.h | 4 | ||||
-rw-r--r-- | src/lib/rng/hmac_rng/hmac_rng.cpp | 40 | ||||
-rw-r--r-- | src/lib/rng/hmac_rng/hmac_rng.h | 6 | ||||
-rw-r--r-- | src/lib/rng/rng.cpp | 15 | ||||
-rw-r--r-- | src/lib/rng/rng.h | 40 | ||||
-rw-r--r-- | src/lib/rng/system_rng/system_rng.cpp | 24 | ||||
-rw-r--r-- | src/lib/rng/system_rng/system_rng.h | 7 | ||||
-rw-r--r-- | src/lib/rng/x931_rng/x931_rng.cpp | 7 | ||||
-rw-r--r-- | src/lib/rng/x931_rng/x931_rng.h | 5 |
11 files changed, 124 insertions, 41 deletions
diff --git a/src/lib/rng/auto_rng/auto_rng.h b/src/lib/rng/auto_rng/auto_rng.h index a7b28af92..ce0c5a7d2 100644 --- a/src/lib/rng/auto_rng/auto_rng.h +++ b/src/lib/rng/auto_rng/auto_rng.h @@ -25,7 +25,12 @@ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator std::string name() const override { return m_rng->name(); } - void reseed(size_t poll_bits = 256) override { m_rng->reseed(poll_bits); } + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override + { + return m_rng->reseed_with_sources(srcs, poll_bits, poll_timeout); + } void add_entropy(const byte in[], size_t len) override { m_rng->add_entropy(in, len); } diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index ad731b6b3..67325ee1b 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -78,11 +78,13 @@ void HMAC_DRBG::update(const byte input[], size_t input_len) } } -void HMAC_DRBG::reseed(size_t poll_bits) +size_t HMAC_DRBG::reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) { if(m_prng) { - m_prng->reseed(poll_bits); + size_t bits = m_prng->reseed_with_sources(srcs, poll_bits, poll_timeout); if(m_prng->is_seeded()) { @@ -90,7 +92,11 @@ void HMAC_DRBG::reseed(size_t poll_bits) update(input.data(), input.size()); m_reseed_counter = 1; } + + return bits; } + + return 0; } void HMAC_DRBG::add_entropy(const byte input[], size_t length) diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h index c9d0e3d20..bd2d18d47 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.h +++ b/src/lib/rng/hmac_drbg/hmac_drbg.h @@ -24,7 +24,9 @@ class BOTAN_DLL HMAC_DRBG : public RandomNumberGenerator void clear() override; std::string name() const override; - void reseed(size_t poll_bits) override; + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override; void add_entropy(const byte input[], size_t input_len) override; diff --git a/src/lib/rng/hmac_rng/hmac_rng.cpp b/src/lib/rng/hmac_rng/hmac_rng.cpp index 5456b3bac..f5a782526 100644 --- a/src/lib/rng/hmac_rng/hmac_rng.cpp +++ b/src/lib/rng/hmac_rng/hmac_rng.cpp @@ -95,7 +95,11 @@ void HMAC_RNG::randomize(byte out[], size_t length) m_output_since_reseed += length; if(m_output_since_reseed >= BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED) - reseed_with_timeout(BOTAN_RNG_RESEED_POLL_BITS, BOTAN_RNG_AUTO_RESEED_TIMEOUT); + { + reseed_with_sources(Entropy_Sources::global_sources(), + BOTAN_RNG_RESEED_POLL_BITS, + BOTAN_RNG_AUTO_RESEED_TIMEOUT); + } /* HMAC KDF as described in E-t-E, using a CTXinfo of "rng" @@ -112,15 +116,9 @@ void HMAC_RNG::randomize(byte out[], size_t length) } } -/* -* Poll for entropy and reset the internal keys -*/ -void HMAC_RNG::reseed(size_t poll_bits) - { - reseed_with_timeout(poll_bits, BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); - } - -void HMAC_RNG::reseed_with_timeout(size_t poll_bits, std::chrono::milliseconds timeout) +size_t HMAC_RNG::reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds timeout) { /* Using the terminology of E-t-E, XTR is the MAC function (normally @@ -130,20 +128,18 @@ void HMAC_RNG::reseed_with_timeout(size_t poll_bits, std::chrono::milliseconds t a bad poll doesn't wipe us out. */ - double bits_collected = 0; - - typedef std::chrono::high_resolution_clock clock; + typedef std::chrono::system_clock clock; auto deadline = clock::now() + timeout; - Entropy_Accumulator accum( - [&](const byte in[], size_t in_len, double entropy_estimate) - { + double bits_collected = 0; + + Entropy_Accumulator accum([&](const byte in[], size_t in_len, double entropy_estimate) { m_extractor->update(in, in_len); bits_collected += entropy_estimate; return (bits_collected >= poll_bits || clock::now() > deadline); }); - EntropySource::poll_available_sources(accum); + srcs.poll(accum); /* * It is necessary to feed forward poll data. Otherwise, a good poll @@ -172,6 +168,8 @@ void HMAC_RNG::reseed_with_timeout(size_t poll_bits, std::chrono::milliseconds t m_extractor->output_length() * 8); m_output_since_reseed = 0; + + return static_cast<size_t>(bits_collected); } bool HMAC_RNG::is_seeded() const @@ -180,12 +178,16 @@ bool HMAC_RNG::is_seeded() const } /* -* Add user-supplied entropy to the extractor input +* Add user-supplied entropy to the extractor input then reseed +* to incorporate it into the state */ void HMAC_RNG::add_entropy(const byte input[], size_t length) { m_extractor->update(input, length); - reseed_with_timeout(BOTAN_RNG_RESEED_POLL_BITS, BOTAN_RNG_AUTO_RESEED_TIMEOUT); + + reseed_with_sources(Entropy_Sources::global_sources(), + BOTAN_RNG_RESEED_POLL_BITS, + BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); } /* diff --git a/src/lib/rng/hmac_rng/hmac_rng.h b/src/lib/rng/hmac_rng/hmac_rng.h index ba12e665d..1e38daa08 100644 --- a/src/lib/rng/hmac_rng/hmac_rng.h +++ b/src/lib/rng/hmac_rng/hmac_rng.h @@ -32,9 +32,9 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator void clear() override; std::string name() const override; - void reseed(size_t poll_bits) override; - - void reseed_with_timeout(size_t poll_bits, std::chrono::milliseconds ms); + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override; void add_entropy(const byte[], size_t) override; diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp index d4fd5fb10..c17f23dd0 100644 --- a/src/lib/rng/rng.cpp +++ b/src/lib/rng/rng.cpp @@ -7,9 +7,24 @@ #include <botan/rng.h> #include <botan/hmac_rng.h> +#include <botan/entropy_src.h> namespace Botan { +size_t RandomNumberGenerator::reseed(size_t bits_to_collect) + { + return this->reseed_with_timeout(bits_to_collect, + BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); + } + +size_t RandomNumberGenerator::reseed_with_timeout(size_t bits_to_collect, + std::chrono::milliseconds timeout) + { + return this->reseed_with_sources(Entropy_Sources::global_sources(), + bits_to_collect, + timeout); + } + RandomNumberGenerator* RandomNumberGenerator::make_rng() { std::unique_ptr<MessageAuthenticationCode> h1(MessageAuthenticationCode::create("HMAC(SHA-512)")); diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h index a28a676a6..1ce0d5153 100644 --- a/src/lib/rng/rng.h +++ b/src/lib/rng/rng.h @@ -8,13 +8,16 @@ #ifndef BOTAN_RANDOM_NUMBER_GENERATOR_H__ #define BOTAN_RANDOM_NUMBER_GENERATOR_H__ -#include <botan/entropy_src.h> +#include <botan/secmem.h> #include <botan/exceptn.h> +#include <chrono> #include <string> #include <mutex> namespace Botan { +class Entropy_Sources; + /** * This class represents a random number (RNG) generator object. */ @@ -100,11 +103,29 @@ class BOTAN_DLL RandomNumberGenerator virtual std::string name() const = 0; /** - * Seed this RNG using the entropy sources it contains. + * Seed this RNG using the global entropy sources and default timeout + * @param bits_to_collect is the number of bits of entropy to + attempt to gather from the entropy sources + */ + size_t reseed(size_t bits_to_collect); + + /** + * Seed this RNG using the global entropy sources * @param bits_to_collect is the number of bits of entropy to attempt to gather from the entropy sources + * @param poll_timeout try not to run longer than this, no matter what */ - virtual void reseed(size_t bits_to_collect) = 0; + size_t reseed_with_timeout(size_t bits_to_collect, + std::chrono::milliseconds poll_timeout); + + /** + * Poll provided sources for up to poll_bits bits of entropy + * or until the timeout expires. Returns estimate of the number + * of bits collected. + */ + virtual size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) = 0; /** * Add entropy to this RNG. @@ -135,7 +156,12 @@ class BOTAN_DLL Null_RNG : public RandomNumberGenerator std::string name() const override { return "Null_RNG"; } - void reseed(size_t) override {} + size_t reseed_with_sources(Entropy_Sources&, size_t, + std::chrono::milliseconds) override + { + return 0; + } + bool is_seeded() const override { return false; } void add_entropy(const byte[], size_t) override {} }; @@ -170,10 +196,12 @@ class BOTAN_DLL Serialized_RNG : public RandomNumberGenerator return m_rng->name(); } - void reseed(size_t poll_bits) override + size_t reseed_with_sources(Entropy_Sources& src, + size_t bits, + std::chrono::milliseconds msec) override { std::lock_guard<std::mutex> lock(m_mutex); - m_rng->reseed(poll_bits); + return m_rng->reseed_with_sources(src, bits, msec); } void add_entropy(const byte in[], size_t len) override diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp index 8b949d071..02ad07736 100644 --- a/src/lib/rng/system_rng/system_rng.cpp +++ b/src/lib/rng/system_rng/system_rng.cpp @@ -40,8 +40,18 @@ class System_RNG_Impl : public RandomNumberGenerator void clear() override {} std::string name() const override { return "system"; } - void reseed(size_t) override {} - void add_entropy(const byte[], size_t) override {} + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override + { + return 0; + } + + void add_entropy(const byte[], size_t) override + { + // We could write this back to /dev/urandom to help seed the PRNG + // Unclear if this is valuable on current systems + } private: #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) @@ -55,14 +65,18 @@ System_RNG_Impl::System_RNG_Impl() { #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) - if(!CryptAcquireContext(&m_prov, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + if(!CryptAcquireContext(&m_prov, 0, 0, BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT)) throw std::runtime_error("System_RNG failed to acquire crypto provider"); #else - m_fd = ::open("/dev/urandom", O_RDONLY); +#ifndef O_NOCTTY + #define O_NOCTTY 0 +#endif + + m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY); if(m_fd < 0) - throw std::runtime_error("System_RNG failed to open /dev/urandom"); + throw std::runtime_error("System_RNG failed to open RNG device"); #endif } diff --git a/src/lib/rng/system_rng/system_rng.h b/src/lib/rng/system_rng/system_rng.h index 0f4b94725..6290b8769 100644 --- a/src/lib/rng/system_rng/system_rng.h +++ b/src/lib/rng/system_rng/system_rng.h @@ -35,7 +35,12 @@ class BOTAN_DLL System_RNG : public RandomNumberGenerator std::string name() const override { return m_rng.name(); } - void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); } + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override + { + return m_rng.reseed_with_sources(srcs, poll_bits, poll_timeout); + } void add_entropy(const byte in[], size_t len) override { m_rng.add_entropy(in, len); } private: diff --git a/src/lib/rng/x931_rng/x931_rng.cpp b/src/lib/rng/x931_rng/x931_rng.cpp index d531cf4a9..020d9a5a5 100644 --- a/src/lib/rng/x931_rng/x931_rng.cpp +++ b/src/lib/rng/x931_rng/x931_rng.cpp @@ -72,10 +72,13 @@ void ANSI_X931_RNG::rekey() } } -void ANSI_X931_RNG::reseed(size_t poll_bits) +size_t ANSI_X931_RNG::reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) { - m_prng->reseed(poll_bits); + size_t bits = m_prng->reseed_with_sources(srcs, poll_bits, poll_timeout); rekey(); + return bits; } void ANSI_X931_RNG::add_entropy(const byte input[], size_t length) diff --git a/src/lib/rng/x931_rng/x931_rng.h b/src/lib/rng/x931_rng/x931_rng.h index 899fed956..ed7124a08 100644 --- a/src/lib/rng/x931_rng/x931_rng.h +++ b/src/lib/rng/x931_rng/x931_rng.h @@ -24,7 +24,10 @@ class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator void clear() override; std::string name() const override; - void reseed(size_t poll_bits) override; + size_t reseed_with_sources(Entropy_Sources& srcs, + size_t poll_bits, + std::chrono::milliseconds poll_timeout) override; + void add_entropy(const byte[], size_t) override; /** |