Botan 3.5.0
Crypto and TLS for C&
entropy_srcs.cpp
Go to the documentation of this file.
1/*
2* Entropy Source Polling
3* (C) 2008-2010,2015 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/entropy_src.h>
9
10#include <botan/rng.h>
11
12#if defined(BOTAN_HAS_SYSTEM_RNG)
13 #include <botan/system_rng.h>
14#endif
15
16#if defined(BOTAN_HAS_PROCESSOR_RNG)
17 #include <botan/processor_rng.h>
18#endif
19
20#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
21 #include <botan/internal/rdseed.h>
22#endif
23
24#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
25 #include <botan/internal/es_win32.h>
26#endif
27
28#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
29 #include <botan/internal/getentropy.h>
30#endif
31
32namespace Botan {
33
34namespace {
35
36#if defined(BOTAN_HAS_SYSTEM_RNG)
37
38class System_RNG_EntropySource final : public Entropy_Source {
39 public:
40 size_t poll(RandomNumberGenerator& rng) override {
41 const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS;
42 rng.reseed_from_rng(system_rng(), poll_bits);
43 return poll_bits;
44 }
45
46 std::string name() const override { return "system_rng"; }
47};
48
49#endif
50
51#if defined(BOTAN_HAS_PROCESSOR_RNG)
52
53class Processor_RNG_EntropySource final : public Entropy_Source {
54 public:
55 size_t poll(RandomNumberGenerator& rng) override {
56 /*
57 * Intel's documentation for RDRAND at
58 * https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
59 * claims that software can guarantee a reseed event by polling enough data:
60 * "There is an upper bound of 511 samples per seed in the implementation
61 * where samples are 128 bits in size and can provide two 64-bit random
62 * numbers each."
63 *
64 * By requesting 65536 bits we are asking for 512 samples and thus are assured
65 * that at some point in producing the output, at least one reseed of the
66 * internal state will occur.
67 *
68 * The reseeding conditions of the POWER and ARM processor RNGs are not known
69 * but probably work in a somewhat similar manner. The exact amount requested
70 * may be tweaked if and when such conditions become publically known.
71 */
72 const size_t poll_bits = 65536;
73 rng.reseed_from_rng(m_hwrng, poll_bits);
74 // Avoid trusting a black box, don't count this as contributing entropy:
75 return 0;
76 }
77
78 std::string name() const override { return m_hwrng.name(); }
79
80 private:
81 Processor_RNG m_hwrng;
82};
83
84#endif
85
86} // namespace
87
88std::unique_ptr<Entropy_Source> Entropy_Source::create(std::string_view name) {
89#if defined(BOTAN_HAS_SYSTEM_RNG)
90 if(name == "system_rng") {
91 return std::make_unique<System_RNG_EntropySource>();
92 }
93#endif
94
95#if defined(BOTAN_HAS_PROCESSOR_RNG)
96 if(name == "hwrng") {
98 return std::make_unique<Processor_RNG_EntropySource>();
99 }
100 }
101#endif
102
103#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
104 if(name == "rdseed") {
105 return std::make_unique<Intel_Rdseed>();
106 }
107#endif
108
109#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
110 if(name == "getentropy") {
111 return std::make_unique<Getentropy>();
112 }
113#endif
114
115#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
116 if(name == "system_stats") {
117 return std::make_unique<Win32_EntropySource>();
118 }
119#endif
120
122 return nullptr;
123}
124
125void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src) {
126 if(src) {
127 m_srcs.push_back(std::move(src));
128 }
129}
130
131std::vector<std::string> Entropy_Sources::enabled_sources() const {
132 std::vector<std::string> sources;
133 sources.reserve(m_srcs.size());
134 for(const auto& src : m_srcs) {
135 sources.push_back(src->name());
136 }
137 return sources;
138}
139
140size_t Entropy_Sources::poll(RandomNumberGenerator& rng, size_t poll_bits, std::chrono::milliseconds timeout) {
141 typedef std::chrono::system_clock clock;
142
143 auto deadline = clock::now() + timeout;
144
145 size_t bits_collected = 0;
146
147 for(auto& src : m_srcs) {
148 bits_collected += src->poll(rng);
149
150 if(bits_collected >= poll_bits || clock::now() > deadline) {
151 break;
152 }
153 }
154
155 return bits_collected;
156}
157
158size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, std::string_view the_src) {
159 for(auto& src : m_srcs) {
160 if(src->name() == the_src) {
161 return src->poll(rng);
162 }
163 }
164
165 return 0;
166}
167
168Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources) {
169 for(auto&& src_name : sources) {
171 }
172}
173
175 static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES);
176
177 return global_entropy_sources;
178}
179
180} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
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)
size_t poll(RandomNumberGenerator &rng, size_t bits, std::chrono::milliseconds timeout)
std::vector< std::string > enabled_sources() const
std::string name
int(* final)(unsigned char *, CTX *)
#define BOTAN_ENTROPY_DEFAULT_SOURCES
Definition build.h:457
#define BOTAN_RNG_RESEED_POLL_BITS
Definition build.h:449
RandomNumberGenerator & system_rng()