/* * Entropy Source Polling * (C) 2008-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_EGD) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) #include #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) #include #endif namespace Botan { std::unique_ptr Entropy_Source::create(const std::string& name) { if(name == "timestamp") { #if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) return std::unique_ptr(new High_Resolution_Timestamp); #endif } if(name == "rdrand") { #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND) return std::unique_ptr(new Intel_Rdrand); #endif } if(name == "proc_info") { #if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER) return std::unique_ptr(new UnixProcessInfo_EntropySource); #endif } if(name == "darwin_secrandom") { #if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM) return std::unique_ptr(new Darwin_SecRandom); #endif } if(name == "dev_random") { #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) return std::unique_ptr(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES)); } if(name == "win32_cryptoapi") { #elif defined(BOTAN_HAS_ENTROPY_SRC_CAPI) return std::unique_ptr(new Win32_CAPI_EntropySource); #endif } if(name == "proc_walk") { #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER) return std::unique_ptr(new ProcWalking_EntropySource("/proc")); #endif } if(name == "system_stats") { #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) return std::unique_ptr(new Win32_EntropySource); #elif defined(BOTAN_HAS_ENTROPY_SRC_BEOS) return std::unique_ptr(new BeOS_EntropySource); #endif } if(name == "unix_procs") { #if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER) return std::unique_ptr(new Unix_EntropySource(BOTAN_ENTROPY_SAFE_PATHS)); #endif } if(name == "egd") { #if defined(BOTAN_HAS_ENTROPY_SRC_EGD) return std::unique_ptr(new EGD_EntropySource(BOTAN_ENTROPY_EGD_PATHS)); #endif } return std::unique_ptr(); } void Entropy_Sources::add_source(std::unique_ptr src) { if(src.get()) { m_srcs.push_back(src.release()); } } std::vector Entropy_Sources::enabled_sources() const { std::vector 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; } } bool Entropy_Sources::poll_just(Entropy_Accumulator& accum, const std::string& the_src) { for(size_t i = 0; i != m_srcs.size(); ++i) { if(m_srcs[i]->name() == the_src) { m_srcs[i]->poll(accum); return true; } } return false; } Entropy_Sources::Entropy_Sources(const std::vector& sources) { for(auto&& src_name : sources) { add_source(Entropy_Source::create(src_name)); } } Entropy_Sources::~Entropy_Sources() { for(size_t i = 0; i != m_srcs.size(); ++i) { 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; } }