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