Botan  2.1.0
Crypto and TLS for C++11
rng.h
Go to the documentation of this file.
1 /*
2 * Random Number Generator base classes
3 * (C) 1999-2009,2015,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_RANDOM_NUMBER_GENERATOR_H__
9 #define BOTAN_RANDOM_NUMBER_GENERATOR_H__
10 
11 #include <botan/entropy_src.h>
12 #include <botan/secmem.h>
13 #include <botan/exceptn.h>
14 #include <botan/mutex.h>
15 #include <chrono>
16 #include <string>
17 
18 namespace Botan {
19 
20 class Entropy_Sources;
21 
22 /**
23 * An interface to a cryptographic random number generator
24 */
25 class BOTAN_DLL RandomNumberGenerator
26  {
27  public:
28  virtual ~RandomNumberGenerator() = default;
29 
30  RandomNumberGenerator() = default;
31 
32  /*
33  * Never copy a RNG, create a new one
34  */
35  RandomNumberGenerator(const RandomNumberGenerator& rng) = delete;
36  RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete;
37 
38  /**
39  * Randomize a byte array.
40  * @param output the byte array to hold the random output.
41  * @param length the length of the byte array output in bytes.
42  */
43  virtual void randomize(uint8_t output[], size_t length) = 0;
44 
45  /**
46  * Incorporate some additional data into the RNG state. For
47  * example adding nonces or timestamps from a peer's protocol
48  * message can help hedge against VM state rollback attacks.
49  * A few RNG types do not accept any externally provided input,
50  * in which case this function is a no-op.
51  *
52  * @param input a byte array containg the entropy to be added
53  * @param length the length of the byte array in
54  */
55  virtual void add_entropy(const uint8_t input[], size_t length) = 0;
56 
57  /**
58  * Incorporate some additional data into the RNG state.
59  */
60  template<typename T> void add_entropy_T(const T& t)
61  {
62  this->add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T));
63  }
64 
65  /**
66  * Incorporate entropy into the RNG state then produce output.
67  * Some RNG types implement this using a single operation, default
68  * calls add_entropy + randomize in sequence.
69  *
70  * Use this to further bind the outputs to your current
71  * process/protocol state. For instance if generating a new key
72  * for use in a session, include a session ID or other such
73  * value. See NIST SP 800-90 A, B, C series for more ideas.
74  *
75  * @param output buffer to hold the random output
76  * @param output_len size of the output buffer in bytes
77  * @param input entropy buffer to incorporate
78  * @param input_len size of the input buffer in bytes
79  */
80  virtual void randomize_with_input(uint8_t output[], size_t output_len,
81  const uint8_t input[], size_t input_len);
82 
83  /**
84  * This calls `randomize_with_input` using some timestamps as extra input.
85  *
86  * For a stateful RNG using non-random but potentially unique data the
87  * extra input can help protect against problems with fork, VM state
88  * rollback, or other cases where somehow an RNG state is duplicated. If
89  * both of the duplicated RNG states later incorporate a timestamp (and the
90  * timestamps don't themselves repeat), their outputs will diverge.
91  */
92  virtual void randomize_with_ts_input(uint8_t output[], size_t output_len);
93 
94  /**
95  * @return the name of this RNG type
96  */
97  virtual std::string name() const = 0;
98 
99  /**
100  * Clear all internally held values of this RNG
101  * @post is_seeded() == false
102  */
103  virtual void clear() = 0;
104 
105  /**
106  * Check whether this RNG is seeded.
107  * @return true if this RNG was already seeded, false otherwise.
108  */
109  virtual bool is_seeded() const = 0;
110 
111  /**
112  * Poll provided sources for up to poll_bits bits of entropy
113  * or until the timeout expires. Returns estimate of the number
114  * of bits collected.
115  */
116  virtual size_t reseed(Entropy_Sources& srcs,
117  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
118  std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT);
119 
120  /**
121  * Reseed by reading specified bits from the RNG
122  */
123  virtual void reseed_from_rng(RandomNumberGenerator& rng,
124  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS);
125 
126  // Some utility functions built on the interface above:
127 
128  /**
129  * Return a random vector
130  * @param bytes number of bytes in the result
131  * @return randomized vector of length bytes
132  */
134  {
135  secure_vector<uint8_t> output(bytes);
136  this->randomize(output.data(), output.size());
137  return output;
138  }
139 
140  /**
141  * Return a random byte
142  * @return random byte
143  */
144  uint8_t next_byte()
145  {
146  uint8_t b;
147  this->randomize(&b, 1);
148  return b;
149  }
150 
151  /**
152  * @return a random byte that is greater than zero
153  */
155  {
156  uint8_t b = this->next_byte();
157  while(b == 0)
158  b = this->next_byte();
159  return b;
160  }
161 
162  /**
163  * Create a seeded and active RNG object for general application use
164  * Added in 1.8.0
165  * Use AutoSeeded_RNG instead
166  */
167  BOTAN_DEPRECATED("Use AutoSeeded_RNG")
168  static RandomNumberGenerator* make_rng();
169  };
170 
171 /**
172 * Convenience typedef
173 */
175 
176 /**
177 * Hardware_RNG has no members but exists to tag hardware RNG types
178 * (PKCS11_RNG, TPM_RNG, RDRAND_RNG)
179 */
180 class BOTAN_DLL Hardware_RNG : public RandomNumberGenerator
181  {
182  };
183 
184 /**
185 * Null/stub RNG - fails if you try to use it for anything
186 * This is not generally useful except for in certain tests
187 */
188 class BOTAN_DLL Null_RNG final : public RandomNumberGenerator
189  {
190  public:
191  bool is_seeded() const override { return false; }
192 
193  void clear() override {}
194 
195  void randomize(uint8_t[], size_t) override
196  {
197  throw PRNG_Unseeded("Null_RNG called");
198  }
199 
200  void add_entropy(const uint8_t[], size_t) override {}
201 
202  std::string name() const override { return "Null_RNG"; }
203  };
204 
205 #if defined(BOTAN_TARGET_OS_HAS_THREADS)
206 /**
207 * Wraps access to a RNG in a mutex
208 * Note that most of the time it's much better to use a RNG per thread
209 * otherwise the RNG will act as an unnecessary contention point
210 */
211 class BOTAN_DLL Serialized_RNG final : public RandomNumberGenerator
212  {
213  public:
214  void randomize(uint8_t out[], size_t len) override
215  {
216  lock_guard_type<mutex_type> lock(m_mutex);
217  m_rng->randomize(out, len);
218  }
219 
220  bool is_seeded() const override
221  {
222  lock_guard_type<mutex_type> lock(m_mutex);
223  return m_rng->is_seeded();
224  }
225 
226  void clear() override
227  {
228  lock_guard_type<mutex_type> lock(m_mutex);
229  m_rng->clear();
230  }
231 
232  std::string name() const override
233  {
234  lock_guard_type<mutex_type> lock(m_mutex);
235  return m_rng->name();
236  }
237 
238  size_t reseed(Entropy_Sources& src,
239  size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
240  std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override
241  {
242  lock_guard_type<mutex_type> lock(m_mutex);
243  return m_rng->reseed(src, poll_bits, poll_timeout);
244  }
245 
246  void add_entropy(const uint8_t in[], size_t len) override
247  {
248  lock_guard_type<mutex_type> lock(m_mutex);
249  m_rng->add_entropy(in, len);
250  }
251 
252  BOTAN_DEPRECATED("Use Serialized_RNG(new AutoSeeded_RNG)") Serialized_RNG();
253 
254  explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
255  private:
256  mutable mutex_type m_mutex;
257  std::unique_ptr<RandomNumberGenerator> m_rng;
258  };
259 #endif
260 
261 }
262 
263 #endif
void add_entropy(const uint8_t[], size_t) override
Definition: rng.h:200
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:133
std::string name() const override
Definition: rng.h:202
void randomize(uint8_t[], size_t) override
Definition: rng.h:195
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
class BOTAN_DLL BOTAN_DEPRECATED("LibraryInitializer is no longer required") LibraryInitializer
Definition: init.h:22
uint8_t next_nonzero_byte()
Definition: rng.h:154
void add_entropy_T(const T &t)
Definition: rng.h:60
bool is_seeded() const override
Definition: rng.h:191
Definition: alg_id.cpp:13
RandomNumberGenerator & m_rng
Definition: ecdh.cpp:52
void clear() override
Definition: rng.h:193