8#include <botan/entropy_src.h>
10#include <botan/assert.h>
12#include <botan/internal/target_info.h>
14#if defined(BOTAN_HAS_SYSTEM_RNG)
15 #include <botan/system_rng.h>
18#if defined(BOTAN_HAS_PROCESSOR_RNG)
19 #include <botan/processor_rng.h>
22#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
23 #include <botan/internal/rdseed.h>
26#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
27 #include <botan/internal/es_win32.h>
30#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
31 #include <botan/internal/getentropy.h>
34#if defined(BOTAN_HAS_JITTER_RNG)
35 #include <botan/jitter_rng.h>
42#if defined(BOTAN_HAS_SYSTEM_RNG)
46 size_t poll(RandomNumberGenerator& rng)
override {
47 const size_t poll_bits = RandomNumberGenerator::DefaultPollBits;
52 std::string name()
const override {
return "system_rng"; }
57#if defined(BOTAN_HAS_PROCESSOR_RNG)
61 size_t poll(RandomNumberGenerator& rng)
override {
78 const size_t poll_bits = 65536;
79 rng.reseed_from_rng(m_hwrng, poll_bits);
84 std::string name()
const override {
return m_hwrng.
name(); }
87 Processor_RNG m_hwrng;
92#if defined(BOTAN_HAS_JITTER_RNG)
96 size_t poll(RandomNumberGenerator& rng)
override {
97 rng.reseed_from_rng(m_rng);
98 return RandomNumberGenerator::DefaultPollBits;
101 std::string name()
const override {
return m_rng.
name(); }
112#if defined(BOTAN_HAS_SYSTEM_RNG)
113 if(
name ==
"system_rng") {
114 return std::make_unique<System_RNG_EntropySource>();
118#if defined(BOTAN_HAS_PROCESSOR_RNG)
119 if(
name ==
"hwrng") {
121 return std::make_unique<Processor_RNG_EntropySource>();
126#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
127 if(
name ==
"rdseed") {
128 return std::make_unique<Intel_Rdseed>();
132#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
133 if(
name ==
"getentropy") {
134 return std::make_unique<Getentropy>();
138#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
139 if(
name ==
"system_stats") {
140 return std::make_unique<Win32_EntropySource>();
144#if defined(BOTAN_HAS_JITTER_RNG)
145 if(
name ==
"jitter_rng") {
146 return std::make_unique<Jitter_RNG_EntropySource>();
156 m_srcs.push_back(std::move(src));
161 std::vector<std::string> sources;
162 sources.reserve(m_srcs.size());
163 for(
const auto& src : m_srcs) {
164 sources.push_back(src->name());
170#if defined(BOTAN_TARGET_OS_HAS_SYSTEM_CLOCK)
171 typedef std::chrono::system_clock clock;
172 auto timeout_expired = [to = clock::now() + timeout] {
return clock::now() > to; };
174 auto timeout_expired = [] {
return false; };
177 size_t bits_collected = 0;
179 for(
auto& src : m_srcs) {
180 bits_collected += src->poll(rng);
182 if(bits_collected >= poll_bits || timeout_expired()) {
187 return bits_collected;
191 for(
auto& src : m_srcs) {
192 if(src->name() == the_src) {
193 return src->poll(rng);
201 for(
auto&& src_name : sources) {
207 static Entropy_Sources global_entropy_sources({
"rdseed",
"hwrng",
"getentropy",
"system_rng",
"system_stats"});
209 return global_entropy_sources;
virtual std::string name() const =0
static std::unique_ptr< Entropy_Source > create(std::string_view type)
static Entropy_Sources & global_sources()
size_t poll_just(RandomNumberGenerator &rng, std::string_view src)
void add_source(std::unique_ptr< Entropy_Source > src)
Entropy_Sources()=default
size_t poll(RandomNumberGenerator &rng, size_t bits, std::chrono::milliseconds timeout)
std::vector< std::string > enabled_sources() const
RandomNumberGenerator & system_rng()