Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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 */
133 secure_vector<uint8_t> random_vec(size_t bytes)
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 */
154 uint8_t next_nonzero_byte()
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 */
174 typedef RandomNumberGenerator RNG;
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
Botan::Null_RNG::add_entropy
void add_entropy(const uint8_t[], size_t) override
Definition: rng.h:200
Botan::RandomNumberGenerator::next_byte
uint8_t next_byte()
Definition: rng.h:144
Botan::RandomNumberGenerator::random_vec
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:133
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::Null_RNG::name
std::string name() const override
Definition: rng.h:202
Botan::Null_RNG::randomize
void randomize(uint8_t[], size_t) override
Definition: rng.h:195
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::BOTAN_DEPRECATED
class BOTAN_DLL BOTAN_DEPRECATED("LibraryInitializer is no longer required") LibraryInitializer
Definition: init.h:22
Botan::RandomNumberGenerator::next_nonzero_byte
uint8_t next_nonzero_byte()
Definition: rng.h:154
Botan::RandomNumberGenerator::add_entropy_T
void add_entropy_T(const T &t)
Definition: rng.h:60
Botan::Null_RNG::is_seeded
bool is_seeded() const override
Definition: rng.h:191
Botan
Definition: alg_id.cpp:13
Botan::Null_RNG
Definition: rng.h:188
m_rng
RandomNumberGenerator & m_rng
Definition: ecdh.cpp:52
Botan::Null_RNG::clear
void clear() override
Definition: rng.h:193
Botan::Entropy_Sources
Definition: entropy_src.h:51
Botan::PRNG_Unseeded
Definition: exceptn.h:120
Botan::Hardware_RNG
Definition: rng.h:180