Botan  2.4.0
Crypto and TLS for C++11
chacha_rng.h
Go to the documentation of this file.
1 /*
2 * ChaCha_RNG
3 * (C) 2017 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_CHACHA_RNG_H_
9 #define BOTAN_CHACHA_RNG_H_
10 
11 #include <botan/stateful_rng.h>
12 #include <botan/stream_cipher.h>
13 #include <botan/mac.h>
14 
15 namespace Botan {
16 
17 class Entropy_Sources;
18 
19 /**
20 * ChaCha_RNG is a very fast but completely ad-hoc RNG created by
21 * creating a 256-bit random value and using it as a key for ChaCha20.
22 *
23 * The RNG maintains two 256-bit keys, one for HMAC_SHA256 (HK) and the
24 * other for ChaCha20 (CK). To compute a new key in response to
25 * reseeding request or add_entropy calls, ChaCha_RNG computes
26 * CK' = HMAC_SHA256(HK, input_material)
27 * Then a new HK' is computed by running ChaCha20 with the new key to
28 * output 32 bytes:
29 * HK' = ChaCha20(CK')
30 *
31 * Now output can be produced by continuing to produce output with ChaCha20
32 * under CK'
33 *
34 * The first HK (before seeding occurs) is taken as the all zero value.
35 *
36 * @warning This RNG construction is probably fine but is non-standard.
37 * The primary reason to use it is in cases where the other RNGs are
38 * not fast enough.
39 */
40 class BOTAN_PUBLIC_API(2,3) ChaCha_RNG final : public Stateful_RNG
41  {
42  public:
43  /**
44  * Automatic reseeding is disabled completely, as it has no access to
45  * any source for seed material.
46  *
47  * If a fork is detected, the RNG will be unable to reseed itself
48  * in response. In this case, an exception will be thrown rather
49  * than generating duplicated output.
50  */
51  ChaCha_RNG();
52 
53  /**
54  * Provide an initial seed to the RNG, without providing an
55  * underlying RNG or entropy source. Automatic reseeding is
56  * disabled completely, as it has no access to any source for
57  * seed material.
58  *
59  * If a fork is detected, the RNG will be unable to reseed itself
60  * in response. In this case, an exception will be thrown rather
61  * than generating duplicated output.
62  *
63  * @param seed the seed material, should be at least 256 bits
64  */
66 
67  /**
68  * Automatic reseeding from @p underlying_rng will take place after
69  * @p reseed_interval many requests or after a fork was detected.
70  *
71  * @param underlying_rng is a reference to some RNG which will be used
72  * to perform the periodic reseeding
73  * @param reseed_interval specifies a limit of how many times
74  * the RNG will be called before automatic reseeding is performed
75  */
76  ChaCha_RNG(RandomNumberGenerator& underlying_rng,
77  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
78 
79  /**
80  * Automatic reseeding from @p entropy_sources will take place after
81  * @p reseed_interval many requests or after a fork was detected.
82  *
83  * @param entropy_sources will be polled to perform reseeding periodically
84  * @param reseed_interval specifies a limit of how many times
85  * the RNG will be called before automatic reseeding is performed.
86  */
87  ChaCha_RNG(Entropy_Sources& entropy_sources,
88  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
89 
90  /**
91  * Automatic reseeding from @p underlying_rng and @p entropy_sources
92  * will take place after @p reseed_interval many requests or after
93  * a fork was detected.
94  *
95  * @param underlying_rng is a reference to some RNG which will be used
96  * to perform the periodic reseeding
97  * @param entropy_sources will be polled to perform reseeding periodically
98  * @param reseed_interval specifies a limit of how many times
99  * the RNG will be called before automatic reseeding is performed.
100  */
101  ChaCha_RNG(RandomNumberGenerator& underlying_rng,
102  Entropy_Sources& entropy_sources,
103  size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
104 
105  std::string name() const override { return "ChaCha_RNG"; }
106 
107  void clear() override;
108 
109  void randomize(uint8_t output[], size_t output_len) override;
110 
111  void randomize_with_input(uint8_t output[], size_t output_len,
112  const uint8_t input[], size_t input_len) override;
113 
114  void add_entropy(const uint8_t input[], size_t input_len) override;
115 
116  size_t security_level() const override;
117 
118  size_t max_number_of_bytes_per_request() const override { return 0; }
119 
120  private:
121  void update(const uint8_t input[], size_t input_len);
122 
123  std::unique_ptr<MessageAuthenticationCode> m_hmac;
124  std::unique_ptr<StreamCipher> m_chacha;
125  };
126 
127 }
128 
129 #endif
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
std::string name() const override
Definition: chacha_rng.h:105
size_t max_number_of_bytes_per_request() const override
Definition: chacha_rng.h:118
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88