/src/botan/src/lib/rng/chacha_rng/chacha_rng.cpp
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 | | #include <botan/chacha_rng.h> |
9 | | |
10 | | namespace Botan { |
11 | | |
12 | 0 | ChaCha_RNG::ChaCha_RNG() : Stateful_RNG() { |
13 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
14 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
15 | 0 | clear(); |
16 | 0 | } |
17 | | |
18 | 7 | ChaCha_RNG::ChaCha_RNG(std::span<const uint8_t> seed) : Stateful_RNG() { |
19 | 7 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
20 | 7 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
21 | 7 | clear(); |
22 | 7 | add_entropy(seed); |
23 | 7 | } |
24 | | |
25 | | ChaCha_RNG::ChaCha_RNG(RandomNumberGenerator& underlying_rng, size_t reseed_interval) : |
26 | 0 | Stateful_RNG(underlying_rng, reseed_interval) { |
27 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
28 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
29 | 0 | clear(); |
30 | 0 | } |
31 | | |
32 | | ChaCha_RNG::ChaCha_RNG(RandomNumberGenerator& underlying_rng, |
33 | | Entropy_Sources& entropy_sources, |
34 | | size_t reseed_interval) : |
35 | 0 | Stateful_RNG(underlying_rng, entropy_sources, reseed_interval) { |
36 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
37 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
38 | 0 | clear(); |
39 | 0 | } |
40 | | |
41 | | ChaCha_RNG::ChaCha_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) : |
42 | 0 | Stateful_RNG(entropy_sources, reseed_interval) { |
43 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
44 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
45 | 0 | clear(); |
46 | 0 | } |
47 | | |
48 | 7 | void ChaCha_RNG::clear_state() { |
49 | 7 | m_hmac->set_key(std::vector<uint8_t>(m_hmac->output_length(), 0x00)); |
50 | 7 | m_chacha->set_key(m_hmac->final()); |
51 | 7 | } |
52 | | |
53 | 245k | void ChaCha_RNG::generate_output(std::span<uint8_t> output, std::span<const uint8_t> input) { |
54 | 245k | BOTAN_ASSERT_NOMSG(!output.empty()); |
55 | | |
56 | 245k | if(!input.empty()) { |
57 | 0 | update(input); |
58 | 0 | } |
59 | | |
60 | 245k | m_chacha->write_keystream(output); |
61 | 245k | } |
62 | | |
63 | 7 | void ChaCha_RNG::update(std::span<const uint8_t> input) { |
64 | 7 | m_hmac->update(input); |
65 | 7 | m_chacha->set_key(m_hmac->final()); |
66 | 7 | const auto mac_key = m_chacha->keystream_bytes(m_hmac->output_length()); |
67 | 7 | m_hmac->set_key(mac_key); |
68 | 7 | } |
69 | | |
70 | 7 | size_t ChaCha_RNG::security_level() const { |
71 | 7 | return 256; |
72 | 7 | } |
73 | | |
74 | | } // namespace Botan |