aboutsummaryrefslogtreecommitdiffstats
path: root/src/rng
diff options
context:
space:
mode:
Diffstat (limited to 'src/rng')
-rw-r--r--src/rng/hmac_rng/hmac_rng.cpp74
-rw-r--r--src/rng/hmac_rng/hmac_rng.h4
2 files changed, 32 insertions, 46 deletions
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp
index cc4e4f790..86f6acb10 100644
--- a/src/rng/hmac_rng/hmac_rng.cpp
+++ b/src/rng/hmac_rng/hmac_rng.cpp
@@ -37,9 +37,9 @@ void hmac_prf(MessageAuthenticationCode* prf,
*************************************************/
void HMAC_RNG::randomize(byte out[], u32bit length)
{
- // Attempt to seed if we are either unseeded or have generated
- // enouch counters that it seems wise to roll over keys
- if(!is_seeded() || counter >= 8192)
+ /* Attempt to seed if we are either unseeded or have generated
+ enouch counters that it seems wise to roll over keys */
+ if(!is_seeded() || counter >= 16 * 1024)
{
reseed();
@@ -62,6 +62,14 @@ void HMAC_RNG::randomize(byte out[], u32bit length)
}
hmac_prf(prf, K, counter, "rng");
+
+ /* Every once in a while do a fast poll of a entropy source */
+ if(entropy_sources.size() && (counter % 1024 == 0))
+ {
+ u32bit got = entropy_sources.at(source_index)->fast_poll(io_buffer, io_buffer.size());
+ source_index = (source_index + 1) % entropy_sources.size();
+ extractor->update(io_buffer, got);
+ }
}
/**
@@ -73,8 +81,6 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
if(entropy_sources.size())
{
- SecureVector<byte> buffer(128);
-
/**
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
@@ -84,47 +90,25 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
feedback of the current PRK value, into the extractor function.
*/
- /*
- Use the first entropy source (which is normally a timer of some
- kind, producing an 8 byte output) as the new random key for the
- extractor. This takes the function of XTS as described in "On
- Extract-then-Expand Key Derivation Functions and an HMAC-based KDF"
- by Hugo Krawczyk (henceforce, 'E-t-E')
-
- Set the extractor MAC key to this value: it's OK if the timer is
- guessable. Even if the timer remained constant for a particular
- machine, that is fine, as the only purpose is to parameterize the
- hash function. See Krawczyk's paper for details.
- */
- u32bit got = entropy_sources[0]->fast_poll(buffer, buffer.size());
- extractor->set_key(buffer, got);
-
- /*
- Fast poll all sources (except the first one, which we used to
- choose XTS, above)
- */
-
- for(u32bit j = 1; j < entropy_sources.size(); ++j)
+ for(u32bit j = 0; j < entropy_sources.size(); ++j)
{
- u32bit got = entropy_sources[j]->fast_poll(buffer, buffer.size());
-
- extractor->update(buffer, got);
- estimate.update(buffer, got, 96);
+ u32bit got = entropy_sources[j]->fast_poll(io_buffer, io_buffer.size());
+ extractor->update(io_buffer, got);
+ estimate.update(io_buffer, got, 96);
}
/* Limit assumed entropy from fast polls (to ensure we do at
- least a few slow polls)
- */
+ least a few slow polls) */
estimate.set_upper_bound(256);
/* Then do a slow poll, until we think we have got enough entropy
*/
for(u32bit j = 0; j != entropy_sources.size(); ++j)
{
- u32bit got = entropy_sources[j]->slow_poll(buffer, buffer.size());
+ u32bit got = entropy_sources[j]->slow_poll(io_buffer, io_buffer.size());
- extractor->update(buffer, got);
- estimate.update(buffer, got, 256);
+ extractor->update(io_buffer, got);
+ estimate.update(io_buffer, got, 256);
if(estimate.value() > 8 * extractor->OUTPUT_LENGTH)
break;
@@ -158,10 +142,13 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
extractor->update(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
- */
+ and set the PRF key to that*/
prf->set_key(extractor->final());
+ // Now generate a new PRF output to use as the XTS extractor salt
+ hmac_prf(prf, K, counter, "xts");
+ extractor->set_key(K, K.size());
+
// Reset state
K.clear();
counter = 0;
@@ -214,6 +201,7 @@ void HMAC_RNG::clear() throw()
K.clear();
entropy = 0;
counter = 0;
+ source_index = 0;
}
/*************************************************
@@ -229,13 +217,14 @@ std::string HMAC_RNG::name() const
*************************************************/
HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
MessageAuthenticationCode* prf_mac) :
- extractor(extractor_mac), prf(prf_mac)
+ extractor(extractor_mac), prf(prf_mac), io_buffer(128)
{
entropy = 0;
// First PRF inputs are all zero, as specified in section 2
K.create(prf->OUTPUT_LENGTH);
counter = 0;
+ source_index = 0;
/*
Normally we want to feedback PRF output into the input to the
@@ -255,14 +244,11 @@ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
prf_key.length());
/*
- This will only be used as the XTS if no entropy source at all is
- enabled. Normally the first one included (typically a timer) is
- used to choose a new extractor salt each time reseeding is
- performed. However if no entropy sources at all are enabled,
- instead this fixed extractor key will be used.
+ This will be used as the first XTS value when extracting input.
+ XTS values after this one are generated using the PRF.
If I understand the E-t-E paper correctly (specifically Section 4),
- this is safe to do.
+ using this fixed extractor key is safe to do.
*/
std::string xts = "Botan HMAC_RNG XTS";
extractor->set_key(reinterpret_cast<const byte*>(xts.c_str()),
diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h
index e735a7899..4b09c4d13 100644
--- a/src/rng/hmac_rng/hmac_rng.h
+++ b/src/rng/hmac_rng/hmac_rng.h
@@ -47,8 +47,8 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
std::vector<EntropySource*> entropy_sources;
u32bit entropy;
- SecureVector<byte> K;
- u32bit counter;
+ SecureVector<byte> K, io_buffer;
+ u32bit counter, source_index;
};
}