Botan  2.1.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_ENTROPY_SRC_RDRAND)
12  #include <botan/internal/rdrand.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
16  #include <botan/internal/rdseed.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
20  #include <botan/internal/dev_random.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
24  #include <botan/internal/es_capi.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 std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
46  {
47  if(name == "rdrand")
48  {
49 #if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
50  return std::unique_ptr<Entropy_Source>(new Intel_Rdrand);
51 #endif
52  }
53 
54  if(name == "rdseed")
55  {
56 #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
57  return std::unique_ptr<Entropy_Source>(new Intel_Rdseed);
58 #endif
59  }
60 
61  if(name == "darwin_secrandom")
62  {
63 #if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
64  return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom);
65 #endif
66  }
67 
68  if(name == "getentropy")
69  {
70 #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
71  return std::unique_ptr<Entropy_Source>(new Getentropy);
72 #endif
73  }
74 
75  if(name == "dev_random")
76  {
77 #if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
78  return std::unique_ptr<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES));
79 #endif
80  }
81 
82  if(name == "win32_cryptoapi")
83  {
84 #if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
85  return std::unique_ptr<Entropy_Source>(new Win32_CAPI_EntropySource("RSA_FULL"));
86 #endif
87  }
88 
89  if(name == "proc_walk")
90  {
91 #if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
92  const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
93  if(!root_dir.empty())
94  return std::unique_ptr<Entropy_Source>(new ProcWalking_EntropySource(root_dir));
95 #endif
96  }
97 
98  if(name == "system_stats")
99  {
100 #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
101  return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
102 #endif
103  }
104 
105  return std::unique_ptr<Entropy_Source>();
106  }
107 
108 void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src)
109  {
110  if(src.get())
111  {
112  m_srcs.push_back(src.release());
113  }
114  }
115 
116 std::vector<std::string> Entropy_Sources::enabled_sources() const
117  {
118  std::vector<std::string> sources;
119  for(size_t i = 0; i != m_srcs.size(); ++i)
120  {
121  sources.push_back(m_srcs[i]->name());
122  }
123  return sources;
124  }
125 
127  size_t poll_bits,
128  std::chrono::milliseconds timeout)
129  {
130  typedef std::chrono::system_clock clock;
131 
132  auto deadline = clock::now() + timeout;
133 
134  size_t bits_collected = 0;
135 
136  for(Entropy_Source* src : m_srcs)
137  {
138  bits_collected += src->poll(rng);
139 
140  if (bits_collected >= poll_bits || clock::now() > deadline)
141  break;
142  }
143 
144  return bits_collected;
145  }
146 
147 size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src)
148  {
149  for(size_t i = 0; i != m_srcs.size(); ++i)
150  {
151  if(m_srcs[i]->name() == the_src)
152  {
153  return m_srcs[i]->poll(rng);
154  }
155  }
156 
157  return 0;
158  }
159 
160 Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources)
161  {
162  for(auto&& src_name : sources)
163  {
165  }
166  }
167 
169  {
170  for(size_t i = 0; i != m_srcs.size(); ++i)
171  {
172  delete m_srcs[i];
173  m_srcs[i] = nullptr;
174  }
175  m_srcs.clear();
176  }
177 
179  {
180  static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES);
181 
182  return global_entropy_sources;
183  }
184 
185 }
186 
std::vector< std::string > enabled_sources() const
size_t poll_just(RandomNumberGenerator &rng, const std::string &src)
Definition: alg_id.cpp:13
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)