~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/rng/rng.h

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
*/
 
24
class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator
 
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
      */
 
132
      secure_vector<uint8_t> random_vec(size_t bytes)
 
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
      */
 
153
      uint8_t next_nonzero_byte()
 
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
*/
 
173
typedef RandomNumberGenerator RNG;
 
174
 
 
175
/**
 
176
* Hardware_RNG has no members but exists to tag hardware RNG types
 
177
* (PKCS11_RNG, TPM_RNG, RDRAND_RNG)
 
178
*/
 
179
class BOTAN_PUBLIC_API(2,0) Hardware_RNG : public RandomNumberGenerator
 
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
*/
 
189
class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator
 
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