aboutsummaryrefslogtreecommitdiffstats
path: root/src/rng/hmac_rng
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-01-01 21:20:55 +0000
committerlloyd <[email protected]>2014-01-01 21:20:55 +0000
commit197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch)
treecdbd3ddaec051c72f0a757db461973d90c37b97a /src/rng/hmac_rng
parent62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (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.cpp205
-rw-r--r--src/rng/hmac_rng/hmac_rng.h57
-rw-r--r--src/rng/hmac_rng/info.txt5
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>