diff options
author | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
commit | 197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch) | |
tree | cdbd3ddaec051c72f0a757db461973d90c37b97a /src/rng/hmac_rng | |
parent | 62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (diff) |
Shuffle things around. Add NIST X.509 test to build.
Diffstat (limited to 'src/rng/hmac_rng')
-rw-r--r-- | src/rng/hmac_rng/hmac_rng.cpp | 205 | ||||
-rw-r--r-- | src/rng/hmac_rng/hmac_rng.h | 57 | ||||
-rw-r--r-- | src/rng/hmac_rng/info.txt | 5 |
3 files changed, 0 insertions, 267 deletions
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp deleted file mode 100644 index 98ae6439e..000000000 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -* HMAC_RNG -* (C) 2008-2009,2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/hmac_rng.h> -#include <botan/libstate.h> -#include <botan/get_byte.h> -#include <botan/entropy_src.h> -#include <botan/internal/xor_buf.h> -#include <algorithm> -#include <chrono> - -namespace Botan { - -namespace { - -void hmac_prf(MessageAuthenticationCode& prf, - secure_vector<byte>& K, - u32bit& counter, - const std::string& label) - { - typedef std::chrono::high_resolution_clock clock; - - auto timestamp = clock::now().time_since_epoch().count(); - - prf.update(K); - prf.update(label); - prf.update_be(timestamp); - prf.update_be(counter); - prf.final(&K[0]); - - ++counter; - } - -} - -/* -* HMAC_RNG Constructor -*/ -HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor, - MessageAuthenticationCode* prf) : - m_extractor(extractor), m_prf(prf) - { - if(!m_prf->valid_keylength(m_extractor->output_length()) || - !m_extractor->valid_keylength(m_prf->output_length())) - throw Invalid_Argument("HMAC_RNG: Bad algo combination " + - m_extractor->name() + " and " + - m_prf->name()); - - // First PRF inputs are all zero, as specified in section 2 - m_K.resize(m_prf->output_length()); - - /* - Normally we want to feedback PRF outputs to the extractor function - to ensure a single bad poll does not reduce entropy. Thus in reseed - we'll want to invoke the PRF before we reset the PRF key, but until - the first reseed the PRF is unkeyed. Rather than trying to keep - track of this, just set the initial PRF key to constant zero. - Since all PRF inputs in the first reseed are constants, this - amounts to suffixing the seed in the first poll with a fixed - constant string. - - The PRF key will not be used to generate outputs until after reseed - sets m_seeded to true. - */ - secure_vector<byte> prf_key(m_extractor->output_length()); - m_prf->set_key(prf_key); - - /* - Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key. - - This will be used during the first extraction sequence; XTS values - after this one are generated using the PRF. - - If I understand the E-t-E paper correctly (specifically Section 4), - using this fixed extractor key is safe to do. - */ - m_extractor->set_key(prf->process("Botan HMAC_RNG XTS")); - } - -/* -* Generate a buffer of random bytes -*/ -void HMAC_RNG::randomize(byte out[], size_t length) - { - if(!is_seeded()) - { - reseed(256); - if(!is_seeded()) - throw PRNG_Unseeded(name()); - } - - const size_t max_per_prf_iter = m_prf->output_length() / 2; - - /* - HMAC KDF as described in E-t-E, using a CTXinfo of "rng" - */ - while(length) - { - hmac_prf(*m_prf, m_K, m_counter, "rng"); - - const size_t copied = std::min<size_t>(length, max_per_prf_iter); - - copy_mem(out, &m_K[0], copied); - out += copied; - length -= copied; - - m_output_since_reseed += copied; - - if(m_output_since_reseed >= BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED) - reseed(BOTAN_RNG_RESEED_POLL_BITS); - } - } - -/* -* Poll for entropy and reset the internal keys -*/ -void HMAC_RNG::reseed(size_t poll_bits) - { - /* - Using the terminology of E-t-E, XTR is the MAC function (normally - HMAC) seeded with XTS (below) and we form SKM, the key material, by - polling as many sources as we think needed to reach our polling - goal. We then also include feedback of the current PRK so that - a bad poll doesn't wipe us out. - */ - - Entropy_Accumulator_BufferedComputation accum(*m_extractor, poll_bits); - - global_state().poll_available_sources(accum); - - /* - * It is necessary to feed forward poll data. Otherwise, a good poll - * (collecting a large amount of conditional entropy) followed by a - * bad one (collecting little) would be unsafe. Do this by - * generating new PRF outputs using the previous key and feeding - * them into the extractor function. - * - * Cycle the RNG once (CTXinfo="rng"), then generate a new PRF - * output using the CTXinfo "reseed". Provide these values as input - * to the extractor function. - */ - hmac_prf(*m_prf, m_K, m_counter, "rng"); - m_extractor->update(m_K); // K is the CTXinfo=rng PRF output - - hmac_prf(*m_prf, m_K, m_counter, "reseed"); - m_extractor->update(m_K); // K is the CTXinfo=reseed PRF output - - /* Now derive the new PRK using everything that has been fed into - the extractor, and set the PRF key to that */ - m_prf->set_key(m_extractor->final()); - - // Now generate a new PRF output to use as the XTS extractor salt - hmac_prf(*m_prf, m_K, m_counter, "xts"); - m_extractor->set_key(m_K); - - // Reset state - zeroise(m_K); - m_counter = 0; - - m_collected_entropy_estimate = - std::min(m_collected_entropy_estimate + accum.bits_collected(), - m_extractor->output_length() * 8); - - m_output_since_reseed = 0; - } - -bool HMAC_RNG::is_seeded() const - { - return (m_collected_entropy_estimate >= 256); - } - -/* -* Add user-supplied entropy to the extractor input -*/ -void HMAC_RNG::add_entropy(const byte input[], size_t length) - { - m_extractor->update(input, length); - reseed(BOTAN_RNG_RESEED_POLL_BITS); - } - -/* -* Clear memory of sensitive data -*/ -void HMAC_RNG::clear() - { - m_collected_entropy_estimate = 0; - m_extractor->clear(); - m_prf->clear(); - zeroise(m_K); - m_counter = 0; - } - -/* -* Return the name of this type -*/ -std::string HMAC_RNG::name() const - { - return "HMAC_RNG(" + m_extractor->name() + "," + m_prf->name() + ")"; - } - -} diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h deleted file mode 100644 index 8fee5be5a..000000000 --- a/src/rng/hmac_rng/hmac_rng.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* HMAC RNG -* (C) 2008,2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_HMAC_RNG_H__ -#define BOTAN_HMAC_RNG_H__ - -#include <botan/mac.h> -#include <botan/rng.h> -#include <vector> - -namespace Botan { - -/** -* HMAC_RNG - based on the design described in "On Extract-then-Expand -* Key Derivation Functions and an HMAC-based KDF" by Hugo Krawczyk -* (henceforce, 'E-t-E') -* -* However it actually can be parameterized with any two MAC functions, -* not restricted to HMAC (this variation is also described in -* Krawczyk's paper), for instance one could use HMAC(SHA-512) as the -* extractor and CMAC(AES-256) as the PRF. -*/ -class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator - { - public: - void randomize(byte buf[], size_t len); - bool is_seeded() const; - void clear(); - std::string name() const; - - void reseed(size_t poll_bits); - void add_entropy(const byte[], size_t); - - /** - * @param extractor a MAC used for extracting the entropy - * @param prf a MAC used as a PRF using HKDF construction - */ - HMAC_RNG(MessageAuthenticationCode* extractor, - MessageAuthenticationCode* prf); - private: - std::unique_ptr<MessageAuthenticationCode> m_extractor; - std::unique_ptr<MessageAuthenticationCode> m_prf; - - size_t m_collected_entropy_estimate = 0; - size_t m_output_since_reseed = 0; - - secure_vector<byte> m_K; - u32bit m_counter = 0; - }; - -} - -#endif diff --git a/src/rng/hmac_rng/info.txt b/src/rng/hmac_rng/info.txt deleted file mode 100644 index 36a8a7a34..000000000 --- a/src/rng/hmac_rng/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -define HMAC_RNG 20131128 - -<requires> -mac -</requires> |