aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-07-18 15:15:51 +0000
committerlloyd <[email protected]>2012-07-18 15:15:51 +0000
commitb553c2fbbefb4594b78fc51edced8f8d25b4d7c8 (patch)
treea86c634fe91f4db1c951f79e16e0bb9e3d040d63 /src
parent3a86d597322422eec70f0265f7c2e98a4caea033 (diff)
Some changes to HMAC_RNG:
- Only give out half of K in each iteration. This prevents an attacker who recovers the PRF key and knows some RNG outputs from being able to determine other RNG outputs. - Don't reset the counter on a reseed, and every 1024 outputs (16 Kbytes with default PRF) initiate a poll. - Don't ever reseed when called with add_entropy, just give it to the extractor, as we know that eventually we'll reseed at which time that input will be incorporated.
Diffstat (limited to 'src')
-rw-r--r--src/rng/hmac_rng/hmac_rng.cpp35
-rw-r--r--src/rng/hmac_rng/hmac_rng.h1
2 files changed, 13 insertions, 23 deletions
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp
index da7535b18..c20c3b44e 100644
--- a/src/rng/hmac_rng/hmac_rng.cpp
+++ b/src/rng/hmac_rng/hmac_rng.cpp
@@ -44,11 +44,14 @@ void HMAC_RNG::randomize(byte out[], size_t length)
{
hmac_prf(prf, K, counter, "rng");
- const size_t copied = std::min<size_t>(K.size(), length);
+ const size_t copied = std::min<size_t>(K.size() / 2, length);
copy_mem(out, &K[0], copied);
out += copied;
length -= copied;
+
+ if(counter % 1024 == 0)
+ reseed(128);
}
}
@@ -60,10 +63,9 @@ 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
- fast polling each source, and then slow polling as many as we think
- we need (in the following loop), and feeding all of the poll
- results, along with any optional user input, along with, finally,
- feedback of the current PRK value, into the extractor function.
+ 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(*extractor, poll_bits);
@@ -107,12 +109,10 @@ void HMAC_RNG::reseed(size_t poll_bits)
// Reset state
zeroise(K);
- counter = 0;
- user_input_len = 0;
/*
- Consider ourselves seeded once we've collected an estimated 128 bits of
- entropy in a single poll.
+ * Consider ourselves seeded once we've collected an estimated 128 bits of
+ * entropy in a single poll.
*/
if(seeded == false && accum.bits_collected() >= 128)
seeded = true;
@@ -123,19 +123,12 @@ void HMAC_RNG::reseed(size_t poll_bits)
*/
void HMAC_RNG::add_entropy(const byte input[], size_t length)
{
- const size_t USER_ENTROPY_WATERSHED = 64;
-
- extractor->update(input, length);
- user_input_len += length;
-
/*
- * After we've accumulated at least USER_ENTROPY_WATERSHED bytes of
- * user input, reseed. This input will automatically have been
- * included if reseed was called already, as it's just included in
- * the extractor input.
+ * Simply include the data in the extractor input. During the
+ * next periodic reseed, the input will be incorporated into
+ * the state.
*/
- if(user_input_len >= USER_ENTROPY_WATERSHED)
- reseed(0);
+ extractor->update(input, length);
}
/*
@@ -155,7 +148,6 @@ void HMAC_RNG::clear()
prf->clear();
zeroise(K);
counter = 0;
- user_input_len = 0;
seeded = false;
}
@@ -184,7 +176,6 @@ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
K.resize(prf->output_length());
counter = 0;
- user_input_len = 0;
seeded = false;
/*
diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h
index 1e70c00a7..e4339b264 100644
--- a/src/rng/hmac_rng/hmac_rng.h
+++ b/src/rng/hmac_rng/hmac_rng.h
@@ -52,7 +52,6 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
bool seeded;
secure_vector<byte> K, io_buffer;
- size_t user_input_len;
u32bit counter;
};