aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/rng
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rng')
-rw-r--r--src/lib/rng/auto_rng/auto_rng.h7
-rw-r--r--src/lib/rng/hmac_drbg/hmac_drbg.cpp10
-rw-r--r--src/lib/rng/hmac_drbg/hmac_drbg.h4
-rw-r--r--src/lib/rng/hmac_rng/hmac_rng.cpp40
-rw-r--r--src/lib/rng/hmac_rng/hmac_rng.h6
-rw-r--r--src/lib/rng/rng.cpp15
-rw-r--r--src/lib/rng/rng.h40
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp24
-rw-r--r--src/lib/rng/system_rng/system_rng.h7
-rw-r--r--src/lib/rng/x931_rng/x931_rng.cpp7
-rw-r--r--src/lib/rng/x931_rng/x931_rng.h5
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;
/**