From 092c6d68006a2d953d8b622ce2c181a6394aed4e Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 27 Jan 2009 06:27:40 +0000 Subject: Have Entropy_Accumulator dump everything into a BufferedComputation. Since both Randpool and HMAC_RNG fed the input into a MAC anyway, this works nicely. (It would be nicer to use tr1::function but, argh, don't want to fully depend on TR1 quite yet. C++0x cannot come soon enough). This avoids requiring to do run length encoding, it just dumps everything as-is into the MAC. This ensures the buffer is not a potential narrow pipe for the entropy (for instance, one might imagine an entropy source which outputs one random byte every 16 bytes, and the rest some repeating pattern - using a 16 byte buffer, you would only get 8 bits of entropy total, no matter how many times you sampled). --- src/entropy/entropy_acc.cpp | 87 ------------------------------------------- src/entropy/entropy_src.h | 38 +++++++++++-------- src/entropy/info.txt | 1 - src/rng/hmac_rng/hmac_rng.cpp | 4 +- src/rng/randpool/randpool.cpp | 4 +- 5 files changed, 26 insertions(+), 108 deletions(-) delete mode 100644 src/entropy/entropy_acc.cpp (limited to 'src') diff --git a/src/entropy/entropy_acc.cpp b/src/entropy/entropy_acc.cpp deleted file mode 100644 index 9dc0f1405..000000000 --- a/src/entropy/entropy_acc.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/** -* Entropy Accumulator -* (C) 1999-2009 Jack Lloyd -*/ - -#include - -namespace Botan { - -void Entropy_Accumulator::reset_goal(u32bit entropy_goal) - { - goal_bits = entropy_goal; - collected_bits = 0; - - /* - * The buffer is large enough to hold 2*goal_bits of entropy, - * or 128 bits, whichever is larger - */ - entropy_buf.create(std::max(goal_bits / 4, 16)); - io_buffer.destroy(); - } - -MemoryRegion& Entropy_Accumulator::get_io_buffer(u32bit size) - { - io_buffer.create(size); - return io_buffer; - } - -u32bit Entropy_Accumulator::desired_remaining_bits() const - { - if(collected_bits >= goal_bits) - return 0; - return (goal_bits - collected_bits); - } - -bool Entropy_Accumulator::polling_goal_achieved() const - { - return (collected_bits >= goal_bits); - } - -void Entropy_Accumulator::add(const void* in_void, - u32bit length, - double entropy_bits_per_byte) - { - if(length == 0) - return; - - entropy_bits_per_byte = std::max(0.0, std::min(entropy_bits_per_byte, 8.0)); - - const byte* in = static_cast(in_void); - - u32bit buf_i = 0; // write index into entropy_buf - u32bit bytes_collected = 0; - - byte last = 0; - byte count = 0; - - for(u32bit i = 0; i != length; ++i) - { - if(in[i] != last) // run length encode the input - { - entropy_buf[buf_i] ^= last; - buf_i = (buf_i + 1) % entropy_buf.size(); - - if(count > 1) - { - entropy_buf[buf_i] ^= count; - buf_i = (buf_i + 1) % entropy_buf.size(); - } - - ++bytes_collected; - - last = in[i]; - count = 1; - } - else - ++count; - } - - entropy_buf[0] ^= last; - entropy_buf[1] ^= count; - - collected_bits += static_cast(entropy_bits_per_byte * bytes_collected); - collected_bits = std::min(collected_bits, 8 * entropy_buf.size()); - } - -} diff --git a/src/entropy/entropy_src.h b/src/entropy/entropy_src.h index 603bbae15..aea6ad8f2 100644 --- a/src/entropy/entropy_src.h +++ b/src/entropy/entropy_src.h @@ -18,32 +18,40 @@ namespace Botan { class Entropy_Accumulator { public: - Entropy_Accumulator(u32bit entropy_goal) - { reset_goal(entropy_goal); } + Entropy_Accumulator(BufferedComputation& sink, u32bit goal) : + entropy_sink(sink), entropy_goal(goal), collected_bits(0) {} - const MemoryRegion& get_entropy_buffer() const - { return entropy_buf; } - - MemoryRegion& get_io_buffer(u32bit size); - - void reset_goal(u32bit entropy_goal); + /** + @return cached I/O buffer for repeated polls + */ + MemoryRegion& get_io_buffer(u32bit size) + { io_buffer.create(size); return io_buffer; } u32bit bits_collected() const { return collected_bits; } - bool polling_goal_achieved() const; + bool polling_goal_achieved() const + { return (collected_bits >= entropy_goal); } - u32bit desired_remaining_bits() const; + u32bit desired_remaining_bits() const + { + return (collected_bits >= entropy_goal) ? 0 : (entropy_goal - collected_bits); + } - void add(const void* bytes, u32bit length, double bits_per_byte); + void add(const void* bytes, u32bit length, u32bit estimated_entropy) + { + entropy_sink.update(reinterpret_cast(bytes), length); + collected_bits += std::min(estimated_entropy, length * 8); + } template - void add(const T& v, double bits_per_byte) + void add(const T& v, u32bit estimated_entropy) { - add(&v, sizeof(T), bits_per_byte); + add(&v, sizeof(T), estimated_entropy); } private: - SecureVector io_buffer, entropy_buf; - u32bit collected_bits, goal_bits; + BufferedComputation& entropy_sink; + SecureVector io_buffer; + u32bit entropy_goal, collected_bits; }; /** diff --git a/src/entropy/info.txt b/src/entropy/info.txt index e0b0320b1..bac1d593f 100644 --- a/src/entropy/info.txt +++ b/src/entropy/info.txt @@ -4,5 +4,4 @@ load_on auto entropy_src.h -entropy_acc.cpp diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp index f495dda4d..ffdfdc60d 100644 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ b/src/rng/hmac_rng/hmac_rng.cpp @@ -69,7 +69,7 @@ void HMAC_RNG::reseed_with_input(u32bit poll_bits, feedback of the current PRK value, into the extractor function. */ - Entropy_Accumulator accum(poll_bits); + Entropy_Accumulator accum(*extractor, poll_bits); for(u32bit i = 0; i < entropy_sources.size(); ++i) { @@ -83,8 +83,6 @@ void HMAC_RNG::reseed_with_input(u32bit poll_bits, if(input_length) accum.add(input, input_length, 1); - extractor->update(accum.get_entropy_buffer()); - /* It is necessary to feed forward poll data. Otherwise, a good poll (collecting a large amount of conditional entropy) followed by a diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index 1a111e20e..41a8ca23a 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -101,7 +101,7 @@ void Randpool::mix_pool() */ void Randpool::reseed(u32bit poll_bits) { - Entropy_Accumulator accum(poll_bits); + Entropy_Accumulator accum(*mac, poll_bits); for(u32bit i = 0; i != entropy_sources.size(); ++i) { @@ -111,7 +111,7 @@ void Randpool::reseed(u32bit poll_bits) break; } - SecureVector mac_val = mac->process(accum.get_entropy_buffer()); + SecureVector mac_val = mac->final(); xor_buf(pool, mac_val, mac_val.size()); mix_pool(); -- cgit v1.2.3