aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/rng/rng.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rng/rng.cpp')
-rw-r--r--src/lib/rng/rng.cpp140
1 files changed, 29 insertions, 111 deletions
diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp
index 5501c143e..8c2982312 100644
--- a/src/lib/rng/rng.cpp
+++ b/src/lib/rng/rng.cpp
@@ -1,144 +1,62 @@
/*
-* Random Number Generator
-* (C) 1999-2008,2016 Jack Lloyd
+* (C) 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/rng.h>
-#include <botan/auto_rng.h>
-#include <botan/entropy_src.h>
#include <botan/loadstor.h>
#include <botan/internal/os_utils.h>
-#if defined(BOTAN_HAS_HMAC_DRBG)
- #include <botan/hmac_drbg.h>
-#endif
-
-#if defined(BOTAN_HAS_HMAC_RNG)
- #include <botan/hmac_rng.h>
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ #include <botan/auto_rng.h>
#endif
namespace Botan {
-size_t RandomNumberGenerator::reseed(size_t bits_to_collect)
+void RandomNumberGenerator::randomize_with_ts_input(byte output[], size_t output_len)
{
- 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);
- }
-
-size_t RandomNumberGenerator::reseed_with_sources(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout)
- {
- return srcs.poll(*this, poll_bits, poll_timeout);
- }
-
-Stateful_RNG::Stateful_RNG(size_t max_output_before_reseed) : m_max_output_before_reseed(max_output_before_reseed)
- {
- }
-
-void Stateful_RNG::clear()
- {
- m_successful_initialization = false;
- m_bytes_since_reseed = 0;
- m_last_pid = 0;
- }
-
-size_t Stateful_RNG::reseed_with_sources(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout)
- {
- size_t bits_collected = RandomNumberGenerator::reseed_with_sources(srcs, poll_bits, poll_timeout);
-
- if(bits_collected >= poll_bits)
- {
- m_successful_initialization = true;
- m_bytes_since_reseed = 0;
- }
+ /*
+ Form additional input which is provided to the PRNG implementation
+ to paramaterize the KDF output.
+ */
+ byte additional_input[16] = { 0 };
+ store_le(OS::get_system_timestamp_ns(), additional_input);
+ store_le(OS::get_processor_timestamp(), additional_input + 8);
- return bits_collected;
+ randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
}
-void Stateful_RNG::reseed_check(size_t bytes_requested)
+void RandomNumberGenerator::randomize_with_input(byte output[], size_t output_len,
+ const byte input[], size_t input_len)
{
- const bool fork_detected = (m_last_pid > 0) && (OS::get_process_id() != m_last_pid);
-
- m_bytes_since_reseed += bytes_requested;
- m_last_pid = OS::get_process_id();
-
- if(!is_seeded() || fork_detected)
- {
- this->reseed(BOTAN_RNG_RESEED_POLL_BITS);
- }
- else if(m_max_output_before_reseed > 0 && m_bytes_since_reseed >= m_max_output_before_reseed)
- {
- this->reseed_with_timeout(BOTAN_RNG_RESEED_POLL_BITS,
- BOTAN_RNG_AUTO_RESEED_TIMEOUT);
- }
-
- if(!is_seeded())
- {
- throw PRNG_Unseeded(name());
- }
+ this->add_entropy(input, input_len);
+ this->randomize(output, output_len);
}
-void Stateful_RNG::initialize_with(const byte input[], size_t len)
+size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs,
+ size_t poll_bits,
+ std::chrono::milliseconds poll_timeout)
{
- add_entropy(input, len);
- m_successful_initialization = true;
+ return srcs.poll(*this, poll_bits, poll_timeout);
}
-bool Stateful_RNG::is_seeded() const
+void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
{
- return m_successful_initialization;
+ secure_vector<byte> buf(poll_bits / 8);
+ rng.randomize(buf.data(), buf.size());
+ this->add_entropy(buf.data(), buf.size());
}
RandomNumberGenerator* RandomNumberGenerator::make_rng()
{
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
return new AutoSeeded_RNG;
+#else
+ throw Exception("make_rng failed, no AutoSeeded_RNG in this build");
+#endif
}
-AutoSeeded_RNG::AutoSeeded_RNG(size_t max_output_before_reseed)
- {
- m_rng.reset(new BOTAN_AUTO_RNG_DRBG(BOTAN_AUTO_RNG_HASH, max_output_before_reseed));
-
- size_t bits = m_rng->reseed(BOTAN_AUTO_RNG_ENTROPY_TARGET);
-
- if(!m_rng->is_seeded())
- {
- throw Exception("AutoSeeded_RNG failed to gather enough entropy only got " +
- std::to_string(bits) + " bits");
- }
- }
-
-void AutoSeeded_RNG::randomize(byte output[], size_t output_len)
- {
- /*
- Form additional input which is provided to the PRNG implementation
- to paramaterize the KDF output.
- */
- byte additional_input[24] = { 0 };
- store_le(OS::get_system_timestamp_ns(), additional_input);
- store_le(OS::get_processor_timestamp(), additional_input + 8);
- store_le(OS::get_process_id(), additional_input + 16);
- store_le(m_counter++, additional_input + 20);
-
- randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
- }
-
-void AutoSeeded_RNG::randomize_with_input(byte output[], size_t output_len,
- const byte ad[], size_t ad_len)
- {
- m_rng->randomize_with_input(output, output_len, ad, ad_len);
- }
+Serialized_RNG::Serialized_RNG() : m_rng(RandomNumberGenerator::make_rng()) {}
}