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