diff options
author | Jack Lloyd <[email protected]> | 2015-11-24 17:51:59 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-11-24 17:51:59 -0500 |
commit | 5f208fab1890e2ad64b52306eccd82f031425c7a (patch) | |
tree | 6bbbf1408e10538e441e3d603d80ebb2cabc6a78 /src/lib/entropy/entropy_srcs.cpp | |
parent | bf59ffc4de374d7b27b7ab400789ab2723131b7a (diff) |
New reseed_with_sources call on RNGs
Provides an easier way for an application to configure a list of
entropy sources they'd like to use, or add a custom entropy source to
their seeding.
Exposes some toggles for the global/default entropy sources to build.h
Adds basic entropy tests which runs the polls and does sanity checking
on the results, including compression tests if available. These are
less useful for the CSPRNG outputs but a good check for the ones
producing plain ASCII like the /proc reader.
Diffstat (limited to 'src/lib/entropy/entropy_srcs.cpp')
-rw-r--r-- | src/lib/entropy/entropy_srcs.cpp | 144 |
1 files changed, 104 insertions, 40 deletions
diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp index d57160c88..cbf13d488 100644 --- a/src/lib/entropy/entropy_srcs.cpp +++ b/src/lib/entropy/entropy_srcs.cpp @@ -49,83 +49,147 @@ namespace Botan { -namespace { - -std::vector<std::unique_ptr<EntropySource>> get_default_entropy_sources() +std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name) { - std::vector<std::unique_ptr<EntropySource>> sources; - + if(name == "timestamp") + { #if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) - sources.push_back(std::unique_ptr<EntropySource>(new High_Resolution_Timestamp)); + return std::unique_ptr<Entropy_Source>(new High_Resolution_Timestamp); #endif + } + if(name == "rdrand") + { #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) - sources.push_back(std::unique_ptr<EntropySource>(new Intel_Rdrand)); + return std::unique_ptr<Entropy_Source>(new Intel_Rdrand); #endif + } + if(name == "proc_info") + { #if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER) - sources.push_back(std::unique_ptr<EntropySource>(new UnixProcessInfo_EntropySource)); + return std::unique_ptr<Entropy_Source>(new UnixProcessInfo_EntropySource); #endif + } -#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) - sources.push_back(std::unique_ptr<EntropySource>(new Device_EntropySource( - { "/dev/random", "/dev/srandom", "/dev/urandom" } - ))); + if(name == "darwin_secrandom") + { +#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) + return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom); #endif + } -#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) - sources.push_back(std::unique_ptr<EntropySource>(new Win32_CAPI_EntropySource)); + if(name == "dev_random") + { +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) + return std::unique_ptr<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); + } + + if(name == "win32_cryptoapi") + { +#elif defined(BOTAN_HAS_ENTROPY_SRC_CAPI) + return std::unique_ptr<Entropy_Source>(new Win32_CAPI_EntropySource); #endif + } + if(name == "proc_walk") + { #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) - sources.push_back(std::unique_ptr<EntropySource>(new ProcWalking_EntropySource("/proc"))); + return std::unique_ptr<Entropy_Source>(new ProcWalking_EntropySource("/proc")); #endif + } + if(name == "system_stats") + { #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) - sources.push_back(std::unique_ptr<EntropySource>(new Win32_EntropySource)); -#endif - -#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) - sources.push_back(std::unique_ptr<EntropySource>(new BeOS_EntropySource)); + return std::unique_ptr<Entropy_Source>(new Win32_EntropySource); +#elif defined(BOTAN_HAS_ENTROPY_SRC_BEOS) + return std::unique_ptr<Entropy_Source>(new BeOS_EntropySource); #endif + } + if(name == "unix_procs") + { #if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER) - sources.push_back(std::unique_ptr<EntropySource>(new Unix_EntropySource( - { "/bin", "/sbin", "/usr/bin", "/usr/sbin" } - ))); + return std::unique_ptr<Entropy_Source>(new Unix_EntropySource(BOTAN_ENTROPY_SAFE_PATHS)); #endif + } + if(name == "egd") + { #if defined(BOTAN_HAS_ENTROPY_SRC_EGD) - sources.push_back(std::unique_ptr<EntropySource>( - new EGD_EntropySource({ "/var/run/egd-pool", "/dev/egd-pool" }) - )); + return std::unique_ptr<Entropy_Source>(new EGD_EntropySource(BOTAN_ENTROPY_EGD_PATHS)); #endif + } -#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) - sources.push_back(std::unique_ptr<EntropySource>(new Darwin_SecRandom)); -#endif + return std::unique_ptr<Entropy_Source>(); + } +void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src) + { + if(src.get()) + { + m_srcs.push_back(src.release()); + } + } + +std::vector<std::string> Entropy_Sources::enabled_sources() const + { + std::vector<std::string> sources; + for(size_t i = 0; i != m_srcs.size(); ++i) + { + sources.push_back(m_srcs[i]->name()); + } return sources; } -} +void Entropy_Sources::poll(Entropy_Accumulator& accum) + { + for(size_t i = 0; i != m_srcs.size(); ++i) + { + m_srcs[i]->poll(accum); + if(accum.polling_goal_achieved()) + break; + } + } -//static -void EntropySource::poll_available_sources(class Entropy_Accumulator& accum) +bool Entropy_Sources::poll_just(Entropy_Accumulator& accum, const std::string& the_src) { - static std::vector<std::unique_ptr<EntropySource>> g_sources(get_default_entropy_sources()); + for(size_t i = 0; i != m_srcs.size(); ++i) + { + if(m_srcs[i]->name() == the_src) + { + m_srcs[i]->poll(accum); + return true; + } + } - if(g_sources.empty()) - throw std::runtime_error("No entropy sources enabled at build time, RNG poll failed"); + return false; + } - size_t poll_attempt = 0; +Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources) + { + for(auto&& src_name : sources) + { + add_source(Entropy_Source::create(src_name)); + } + } - while(!accum.polling_finished() && poll_attempt < 16) +Entropy_Sources::~Entropy_Sources() + { + for(size_t i = 0; i != m_srcs.size(); ++i) { - const size_t src_idx = poll_attempt % g_sources.size(); - g_sources[src_idx]->poll(accum); - ++poll_attempt; + delete m_srcs[i]; + m_srcs[i] = nullptr; } + m_srcs.clear(); + } + +Entropy_Sources& Entropy_Sources::global_sources() + { + static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES); + + return global_entropy_sources; } } |