diff options
Diffstat (limited to 'src/lib/rng/hmac_drbg/hmac_drbg.cpp')
-rw-r--r-- | src/lib/rng/hmac_drbg/hmac_drbg.cpp | 138 |
1 files changed, 59 insertions, 79 deletions
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp index 67325ee1b..201a9f39b 100644 --- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp +++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp @@ -1,6 +1,6 @@ /* * HMAC_DRBG -* (C) 2014,2015 Jack Lloyd +* (C) 2014,2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -10,53 +10,75 @@ namespace Botan { -HMAC_DRBG::HMAC_DRBG(MessageAuthenticationCode* mac, - RandomNumberGenerator* prng) : - m_mac(mac), - m_prng(prng), - m_V(m_mac->output_length(), 0x01), - m_reseed_counter(0) +HMAC_DRBG::HMAC_DRBG(const std::string& hmac_hash) : + HMAC_DRBG(hmac_hash, BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED) + {} + +HMAC_DRBG::HMAC_DRBG(const std::string& hmac_hash, + size_t max_bytes_before_reseed) : + Stateful_RNG(max_bytes_before_reseed) { - m_mac->set_key(std::vector<byte>(m_mac->output_length(), 0x00)); + const std::string hmac = "HMAC(" + hmac_hash + ")"; + + m_mac = MessageAuthenticationCode::create(hmac); + if(!m_mac) + { + throw Algorithm_Not_Found(hmac); + } + + m_V.resize(m_mac->output_length()); + + clear(); } -HMAC_DRBG::HMAC_DRBG(const std::string& mac_name, - RandomNumberGenerator* prng) : - m_prng(prng), - m_reseed_counter(0) +void HMAC_DRBG::clear() { - m_mac = MessageAuthenticationCode::create(mac_name); - if(!m_mac) - throw Algorithm_Not_Found(mac_name); - m_V = secure_vector<byte>(m_mac->output_length(), 0x01), + for(size_t i = 0; i != m_V.size(); ++i) + m_V[i] = 0x01; m_mac->set_key(std::vector<byte>(m_mac->output_length(), 0x00)); } -void HMAC_DRBG::randomize(byte out[], size_t length) +std::string HMAC_DRBG::name() const { - if(!is_seeded() || m_reseed_counter > BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED) - reseed(m_mac->output_length() * 8); + return "HMAC_DRBG(" + m_mac->name() + ")"; + } - if(!is_seeded()) - throw PRNG_Unseeded(name()); +void HMAC_DRBG::randomize(byte output[], size_t output_len) + { + randomize_with_input(output, output_len, nullptr, 0); + } - while(length) - { - const size_t to_copy = std::min(length, m_V.size()); - m_V = m_mac->process(m_V); - copy_mem(out, m_V.data(), to_copy); +/* +* HMAC_DRBG generation +* See NIST SP800-90A section 10.1.2.5 +*/ +void HMAC_DRBG::randomize_with_input(byte output[], size_t output_len, + const byte input[], size_t input_len) + { + reseed_check(output_len); - length -= to_copy; - out += to_copy; + if(input_len > 0) + { + update(input, input_len); } - m_reseed_counter += length; + while(output_len) + { + const size_t to_copy = std::min(output_len, m_V.size()); + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); + copy_mem(output, m_V.data(), to_copy); + + output += to_copy; + output_len -= to_copy; + } - update(nullptr, 0); // additional_data is always empty + update(input, input_len); } /* * Reset V and the mac key with new values +* See NIST SP800-90A section 10.1.2.2 */ void HMAC_DRBG::update(const byte input[], size_t input_len) { @@ -65,66 +87,24 @@ void HMAC_DRBG::update(const byte input[], size_t input_len) m_mac->update(input, input_len); m_mac->set_key(m_mac->final()); - m_V = m_mac->process(m_V); + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); - if(input_len) + if(input_len > 0) { m_mac->update(m_V); m_mac->update(0x01); m_mac->update(input, input_len); m_mac->set_key(m_mac->final()); - m_V = m_mac->process(m_V); + m_mac->update(m_V.data(), m_V.size()); + m_mac->final(m_V.data()); } } -size_t HMAC_DRBG::reseed_with_sources(Entropy_Sources& srcs, - size_t poll_bits, - std::chrono::milliseconds poll_timeout) +void HMAC_DRBG::add_entropy(const byte input[], size_t input_len) { - if(m_prng) - { - size_t bits = m_prng->reseed_with_sources(srcs, poll_bits, poll_timeout); - - if(m_prng->is_seeded()) - { - secure_vector<byte> input = m_prng->random_vec(m_mac->output_length()); - update(input.data(), input.size()); - m_reseed_counter = 1; - } - - return bits; - } - - return 0; - } - -void HMAC_DRBG::add_entropy(const byte input[], size_t length) - { - update(input, length); - m_reseed_counter = 1; - } - -bool HMAC_DRBG::is_seeded() const - { - return m_reseed_counter > 0; - } - -void HMAC_DRBG::clear() - { - m_reseed_counter = 0; - for(size_t i = 0; i != m_V.size(); ++i) - m_V[i] = 0x01; - - m_mac->set_key(std::vector<byte>(m_mac->output_length(), 0x00)); - - if(m_prng) - m_prng->clear(); - } - -std::string HMAC_DRBG::name() const - { - return "HMAC_DRBG(" + m_mac->name() + ")"; + update(input, input_len); } } |