diff options
Diffstat (limited to 'src/lib/rng/rng.h')
-rw-r--r-- | src/lib/rng/rng.h | 137 |
1 files changed, 45 insertions, 92 deletions
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h index 7da560b85..d1cdcfff2 100644 --- a/src/lib/rng/rng.h +++ b/src/lib/rng/rng.h @@ -8,6 +8,7 @@ #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> @@ -19,7 +20,7 @@ namespace Botan { class Entropy_Sources; /** -* An interface to a generic RNG +* An interface to a cryptographic random number generator */ class BOTAN_DLL RandomNumberGenerator { @@ -45,6 +46,8 @@ class BOTAN_DLL RandomNumberGenerator * Incorporate some additional data into the RNG state. For * example adding nonces or timestamps from a peer's protocol * message can help hedge against VM state rollback attacks. + * A few RNG types do not accept any externally provided input, + * in which case this function is a no-op. * * @param inputs a byte array containg the entropy to be added * @param length the length of the byte array in @@ -56,27 +59,41 @@ class BOTAN_DLL RandomNumberGenerator */ template<typename T> void add_entropy_T(const T& t) { - add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T)); + this->add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T)); } /** - * Incorporate entropy into the RNG state then produce output - * Some RNG types implement this using a single operation. + * Incorporate entropy into the RNG state then produce output. + * Some RNG types implement this using a single operation, default + * calls add_entropy + randomize in sequence. + * + * Use this to further bind the outputs to your current + * process/protocol state. For instance if generating a new key + * for use in a session, include a session ID or other such + * value. See NIST SP 800-90 A, B, C series for more ideas. */ virtual void randomize_with_input(byte output[], size_t output_len, - const byte input[], size_t input_len) - { - this->add_entropy(input, input_len); - this->randomize(output, output_len); - } + const byte input[], size_t input_len); + + /** + * This calls `randomize_with_input` using some timestamps as extra input. + * + * For a stateful RNG using non-random but potentially unique data as the + * additional_input can help protect against problems with fork, VM state + * rollback, or other cases where somehow an RNG state is duplicated. If + * both of the duplicated RNG states later incorporate a timestamp (and the + * timestamps don't themselves repeat), their outputs will diverge. + */ + virtual void randomize_with_ts_input(byte output[], size_t output_len); /** - * Return the name of this object + * Return the name of this RNG type */ virtual std::string name() const = 0; /** - * Clear all internally held values of this RNG. + * Clear all internally held values of this RNG + * @post is_seeded() == false */ virtual void clear() = 0; @@ -91,28 +108,17 @@ class BOTAN_DLL RandomNumberGenerator * 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); + virtual size_t reseed(Entropy_Sources& srcs, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT); /** - * Reseed this RNG from the default entropy sources and a default timeout - * @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, even if - * not enough entropy has been collected + * Reseed by reading specified bits from the RNG */ - size_t reseed(size_t bits_to_collect = BOTAN_RNG_RESEED_POLL_BITS); + virtual void reseed_from_rng(RandomNumberGenerator& rng, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS); - /** - * Reseed this RNG from the default 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, even if - * not enough entropy has been collected - */ - size_t reseed_with_timeout(size_t bits_to_collect, - std::chrono::milliseconds poll_timeout); + // Some utility functions built on the interface above: /** * Return a random vector @@ -122,7 +128,7 @@ class BOTAN_DLL RandomNumberGenerator secure_vector<byte> random_vec(size_t bytes) { secure_vector<byte> output(bytes); - randomize(output.data(), output.size()); + this->randomize(output.data(), output.size()); return output; } @@ -139,9 +145,9 @@ class BOTAN_DLL RandomNumberGenerator byte next_nonzero_byte() { - byte b = next_byte(); + byte b = this->next_byte(); while(b == 0) - b = next_byte(); + b = this->next_byte(); return b; } @@ -150,65 +156,11 @@ class BOTAN_DLL RandomNumberGenerator * Added in 1.8.0 * Use AutoSeeded_RNG instead */ + BOTAN_DEPRECATED("Use AutoSeeded_RNG") static RandomNumberGenerator* make_rng(); }; /** -* Inherited by RNGs which maintain in-process state, like HMAC_DRBG. -* On Unix these RNGs are vulnerable to problems with fork, where the -* RNG state is duplicated, and the parent and child process RNGs will -* produce identical output until one of them reseeds. Stateful_RNG -* reseeds itself whenever a fork is detected, or after a set number of -* bytes have been output. -* -* Not implemented by RNGs which access an external RNG, such as the -* system PRNG or a hardware RNG. -*/ -class BOTAN_DLL Stateful_RNG : public RandomNumberGenerator - { - public: - Stateful_RNG(size_t max_output_before_reseed); - - virtual bool is_seeded() const override final; - - /** - * Consume this input and mark the RNG as initialized regardless - * of the length of the input or the current seeded state of - * the RNG. - */ - void initialize_with(const byte input[], size_t length); - - /** - * Poll provided sources for up to poll_bits bits of entropy - * or until the timeout expires. Returns estimate of the number - * of bits collected. - */ - size_t reseed_with_sources(Entropy_Sources& srcs, - size_t poll_bits, - std::chrono::milliseconds poll_timeout) override; - - protected: - void reseed_check(size_t bytes_requested); - - void clear() override; - - /** - * Mark state as requiring a reseed on next use - */ - void force_reseed() { m_bytes_since_reseed = m_max_output_before_reseed; } - - uint32_t last_pid() const { return m_last_pid; } - - mutable std::mutex m_mutex; - - private: - const size_t m_max_output_before_reseed; - size_t m_bytes_since_reseed = 0; - uint32_t m_last_pid = 0; - bool m_successful_initialization = false; - }; - -/** * Convenience typedef */ typedef RandomNumberGenerator RNG; @@ -271,12 +223,12 @@ class BOTAN_DLL Serialized_RNG final : public RandomNumberGenerator return m_rng->name(); } - size_t reseed_with_sources(Entropy_Sources& src, - size_t bits, - std::chrono::milliseconds msec) override + size_t reseed(Entropy_Sources& src, + size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS, + std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override { std::lock_guard<std::mutex> lock(m_mutex); - return m_rng->reseed_with_sources(src, bits, msec); + return m_rng->reseed(src, poll_bits, poll_timeout); } void add_entropy(const byte in[], size_t len) override @@ -285,7 +237,8 @@ class BOTAN_DLL Serialized_RNG final : public RandomNumberGenerator m_rng->add_entropy(in, len); } - Serialized_RNG() : m_rng(RandomNumberGenerator::make_rng()) {} + BOTAN_DEPRECATED("Create an AutoSeeded_RNG for other constructor") Serialized_RNG(); + explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {} private: mutable std::mutex m_mutex; |