/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 | | ChaCha_RNG::ChaCha_RNG() : Stateful_RNG() |
13 | 0 | { |
14 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
15 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
16 | 0 | clear(); |
17 | 0 | } |
18 | | |
19 | | ChaCha_RNG::ChaCha_RNG(const secure_vector<uint8_t>& seed) : Stateful_RNG() |
20 | 7 | { |
21 | 7 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
22 | 7 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
23 | 7 | clear(); |
24 | 7 | add_entropy(seed.data(), seed.size()); |
25 | 7 | } |
26 | | |
27 | | ChaCha_RNG::ChaCha_RNG(RandomNumberGenerator& underlying_rng, |
28 | | size_t reseed_interval) : |
29 | | Stateful_RNG(underlying_rng, reseed_interval) |
30 | 0 | { |
31 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
32 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
33 | 0 | clear(); |
34 | 0 | } |
35 | | |
36 | | ChaCha_RNG::ChaCha_RNG(RandomNumberGenerator& underlying_rng, |
37 | | Entropy_Sources& entropy_sources, |
38 | | size_t reseed_interval) : |
39 | | Stateful_RNG(underlying_rng, entropy_sources, reseed_interval) |
40 | 0 | { |
41 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
42 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
43 | 0 | clear(); |
44 | 0 | } |
45 | | |
46 | | ChaCha_RNG::ChaCha_RNG(Entropy_Sources& entropy_sources, |
47 | | size_t reseed_interval) : |
48 | | Stateful_RNG(entropy_sources, reseed_interval) |
49 | 0 | { |
50 | 0 | m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)"); |
51 | 0 | m_chacha = StreamCipher::create_or_throw("ChaCha(20)"); |
52 | 0 | clear(); |
53 | 0 | } |
54 | | |
55 | | void ChaCha_RNG::clear_state() |
56 | 7 | { |
57 | 7 | m_hmac->set_key(std::vector<uint8_t>(m_hmac->output_length(), 0x00)); |
58 | 7 | m_chacha->set_key(m_hmac->final()); |
59 | 7 | } |
60 | | |
61 | | void ChaCha_RNG::generate_output(uint8_t output[], size_t output_len, |
62 | | const uint8_t input[], size_t input_len) |
63 | 674k | { |
64 | 674k | if(input_len > 0) |
65 | 0 | { |
66 | 0 | update(input, input_len); |
67 | 0 | } |
68 | | |
69 | 674k | m_chacha->write_keystream(output, output_len); |
70 | 674k | } |
71 | | |
72 | | void ChaCha_RNG::update(const uint8_t input[], size_t input_len) |
73 | 7 | { |
74 | 7 | m_hmac->update(input, input_len); |
75 | 7 | m_chacha->set_key(m_hmac->final()); |
76 | | |
77 | 7 | secure_vector<uint8_t> mac_key(m_hmac->output_length()); |
78 | 7 | m_chacha->write_keystream(mac_key.data(), mac_key.size()); |
79 | 7 | m_hmac->set_key(mac_key); |
80 | 7 | } |
81 | | |
82 | | size_t ChaCha_RNG::security_level() const |
83 | 7 | { |
84 | 7 | return 256; |
85 | 7 | } |
86 | | |
87 | | } |