aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/rng/rng.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rng/rng.h')
-rw-r--r--src/lib/rng/rng.h137
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;