Botan  2.6.0
Crypto and TLS for C++11
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 #include <botan/rng.h>
10 
11 #if defined(BOTAN_HAS_SYSTEM_RNG)
12  #include <botan/system_rng.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
16  #include <botan/internal/rdrand.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
20  #include <botan/internal/rdseed.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
24  #include <botan/internal/dev_random.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
28  #include <botan/internal/es_win32.h>
29 #endif
30 
31 #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
32  #include <botan/internal/proc_walk.h>
33 #endif
34 
35 #if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
36  #include <botan/internal/darwin_secrandom.h>
37 #endif
38 
39 #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
40  #include <botan/internal/getentropy.h>
41 #endif
42 
43 namespace Botan {
44 
45 #if defined(BOTAN_HAS_SYSTEM_RNG)
46 
47 namespace {
48 
49 class System_RNG_EntropySource final : public Entropy_Source
50  {
51  public:
52  size_t poll(RandomNumberGenerator& rng) override
53  {
54  const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS;
55  rng.reseed_from_rng(system_rng(), poll_bits);
56  return poll_bits;
57  }
58 
59  std::string name() const override { return "system_rng"; }
60  };
61 
62 }
63 
64 #endif
65 
66 std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
67  {
68 #if defined(BOTAN_HAS_SYSTEM_RNG)
69  if(name == "system_rng" || name == "win32_cryptoapi")
70  {
71  return std::unique_ptr<Entropy_Source>(new System_RNG_EntropySource);
72  }
73 #endif
74 
75 #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
76  if(name == "rdrand")
77  {
78  return std::unique_ptr<Entropy_Source>(new Intel_Rdrand);
79  }
80 #endif
81 
82 #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
83  if(name == "rdseed")
84  {
85  return std::unique_ptr<Entropy_Source>(new Intel_Rdseed);
86  }
87 #endif
88 
89 #if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
90  if(name == "darwin_secrandom")
91  {
92  return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom);
93  }
94 #endif
95 
96 #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
97  if(name == "getentropy")
98  {
99  return std::unique_ptr<Entropy_Source>(new Getentropy);
100  }
101 #endif
102 
103 #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
104  if(name == "dev_random")
105  {
106  return std::unique_ptr<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES));
107  }
108 #endif
109 
110 #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
111  if(name == "proc_walk")
112  {
113  const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
114  if(!root_dir.empty())
115  return std::unique_ptr<Entropy_Source>(new ProcWalking_EntropySource(root_dir));
116  }
117 #endif
118 
119 #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
120  if(name == "system_stats")
121  {
122  return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
123  }
124 #endif
125 
127  return std::unique_ptr<Entropy_Source>();
128  }
129 
130 void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src)
131  {
132  if(src.get())
133  {
134  m_srcs.push_back(std::move(src));
135  }
136  }
137 
138 std::vector<std::string> Entropy_Sources::enabled_sources() const
139  {
140  std::vector<std::string> sources;
141  for(size_t i = 0; i != m_srcs.size(); ++i)
142  {
143  sources.push_back(m_srcs[i]->name());
144  }
145  return sources;
146  }
147 
149  size_t poll_bits,
150  std::chrono::milliseconds timeout)
151  {
152  typedef std::chrono::system_clock clock;
153 
154  auto deadline = clock::now() + timeout;
155 
156  size_t bits_collected = 0;
157 
158  for(size_t i = 0; i != m_srcs.size(); ++i)
159  {
160  bits_collected += m_srcs[i]->poll(rng);
161 
162  if (bits_collected >= poll_bits || clock::now() > deadline)
163  break;
164  }
165 
166  return bits_collected;
167  }
168 
169 size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src)
170  {
171  for(size_t i = 0; i != m_srcs.size(); ++i)
172  {
173  if(m_srcs[i]->name() == the_src)
174  {
175  return m_srcs[i]->poll(rng);
176  }
177  }
178 
179  return 0;
180  }
181 
182 Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources)
183  {
184  for(auto&& src_name : sources)
185  {
187  }
188  }
189 
191  {
192  static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES);
193 
194  return global_entropy_sources;
195  }
196 
197 }
198 
RandomNumberGenerator & system_rng()
Definition: system_rng.cpp:177
std::vector< std::string > enabled_sources() const
size_t poll_just(RandomNumberGenerator &rng, const std::string &src)
virtual std::string name() const =0
Definition: alg_id.cpp:13
#define BOTAN_UNUSED(...)
Definition: assert.h:117
void add_source(std::unique_ptr< Entropy_Source > src)
static std::unique_ptr< Entropy_Source > create(const std::string &type)
static Entropy_Sources & global_sources()
size_t poll(RandomNumberGenerator &rng, size_t bits, std::chrono::milliseconds timeout)