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