/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/mac.h> |
12 | | #include <botan/stateful_rng.h> |
13 | | #include <botan/stream_cipher.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 | | public: |
42 | | /** |
43 | | * Automatic reseeding is disabled completely, as it has no access to |
44 | | * any source for seed material. |
45 | | * |
46 | | * If a fork is detected, the RNG will be unable to reseed itself |
47 | | * in response. In this case, an exception will be thrown rather |
48 | | * than generating duplicated output. |
49 | | */ |
50 | | ChaCha_RNG(); |
51 | | |
52 | | /** |
53 | | * Provide an initial seed to the RNG, without providing an |
54 | | * underlying RNG or entropy source. Automatic reseeding is |
55 | | * disabled completely, as it has no access to any source for |
56 | | * seed material. |
57 | | * |
58 | | * If a fork is detected, the RNG will be unable to reseed itself |
59 | | * in response. In this case, an exception will be thrown rather |
60 | | * than generating duplicated output. |
61 | | * |
62 | | * @param seed the seed material, should be at least 256 bits |
63 | | */ |
64 | | ChaCha_RNG(std::span<const uint8_t> seed); |
65 | | |
66 | | /** |
67 | | * Automatic reseeding from @p underlying_rng will take place after |
68 | | * @p reseed_interval many requests or after a fork was detected. |
69 | | * |
70 | | * @param underlying_rng is a reference to some RNG which will be used |
71 | | * to perform the periodic reseeding |
72 | | * @param reseed_interval specifies a limit of how many times |
73 | | * the RNG will be called before automatic reseeding is performed |
74 | | */ |
75 | | ChaCha_RNG(RandomNumberGenerator& underlying_rng, size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); |
76 | | |
77 | | /** |
78 | | * Automatic reseeding from @p entropy_sources will take place after |
79 | | * @p reseed_interval many requests or after a fork was detected. |
80 | | * |
81 | | * @param entropy_sources will be polled to perform reseeding periodically |
82 | | * @param reseed_interval specifies a limit of how many times |
83 | | * the RNG will be called before automatic reseeding is performed. |
84 | | */ |
85 | | ChaCha_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); |
86 | | |
87 | | /** |
88 | | * Automatic reseeding from @p underlying_rng and @p entropy_sources |
89 | | * will take place after @p reseed_interval many requests or after |
90 | | * a fork was detected. |
91 | | * |
92 | | * @param underlying_rng is a reference to some RNG which will be used |
93 | | * to perform the periodic reseeding |
94 | | * @param entropy_sources will be polled to perform reseeding periodically |
95 | | * @param reseed_interval specifies a limit of how many times |
96 | | * the RNG will be called before automatic reseeding is performed. |
97 | | */ |
98 | | ChaCha_RNG(RandomNumberGenerator& underlying_rng, |
99 | | Entropy_Sources& entropy_sources, |
100 | | size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL); |
101 | | |
102 | 0 | std::string name() const override { return "ChaCha_RNG"; } |
103 | | |
104 | | size_t security_level() const override; |
105 | | |
106 | 92.8k | size_t max_number_of_bytes_per_request() const override { return 0; } |
107 | | |
108 | | private: |
109 | | void update(std::span<const uint8_t> input) override; |
110 | | |
111 | | void generate_output(std::span<uint8_t> output, std::span<const uint8_t> input) override; |
112 | | |
113 | | void clear_state() override; |
114 | | |
115 | | std::unique_ptr<MessageAuthenticationCode> m_hmac; |
116 | | std::unique_ptr<StreamCipher> m_chacha; |
117 | | }; |
118 | | |
119 | | } // namespace Botan |
120 | | |
121 | | #endif |