/src/botan/build/include/botan/chacha_rng.h
Line | Count | Source (jump to first uncovered line) |
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 | | */ |
65 | | ChaCha_RNG(const secure_vector<uint8_t>& seed); |
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 | 0 | 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 | 0 | 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 |