diff options
author | lloyd <[email protected]> | 2012-07-18 15:15:51 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-07-18 15:15:51 +0000 |
commit | b553c2fbbefb4594b78fc51edced8f8d25b4d7c8 (patch) | |
tree | a86c634fe91f4db1c951f79e16e0bb9e3d040d63 /src | |
parent | 3a86d597322422eec70f0265f7c2e98a4caea033 (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.cpp | 35 | ||||
-rw-r--r-- | src/rng/hmac_rng/hmac_rng.h | 1 |
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; }; |