aboutsummaryrefslogtreecommitdiffstats
path: root/src/randpool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/randpool.cpp')
-rw-r--r--src/randpool.cpp99
1 files changed, 67 insertions, 32 deletions
diff --git a/src/randpool.cpp b/src/randpool.cpp
index abb75c1f0..24086c984 100644
--- a/src/randpool.cpp
+++ b/src/randpool.cpp
@@ -1,6 +1,6 @@
/*************************************************
* Randpool Source File *
-* (C) 1999-2007 Jack Lloyd *
+* (C) 1999-2008 Jack Lloyd *
*************************************************/
#include <botan/randpool.h>
@@ -8,6 +8,7 @@
#include <botan/loadstor.h>
#include <botan/bit_ops.h>
#include <botan/util.h>
+#include <botan/stl_util.h>
#include <algorithm>
namespace Botan {
@@ -18,21 +19,11 @@ namespace {
* PRF based on a MAC *
*************************************************/
enum RANDPOOL_PRF_TAG {
- USER_INPUT = 0,
- CIPHER_KEY = 1,
- MAC_KEY = 2,
- GEN_OUTPUT = 3
+ CIPHER_KEY = 0,
+ MAC_KEY = 1,
+ GEN_OUTPUT = 2
};
-SecureVector<byte> randpool_prf(MessageAuthenticationCode* mac,
- RANDPOOL_PRF_TAG tag,
- const byte in[], u32bit length)
- {
- mac->update(static_cast<byte>(tag));
- mac->update(in, length);
- return mac->final();
- }
-
}
/*************************************************
@@ -41,7 +32,12 @@ SecureVector<byte> randpool_prf(MessageAuthenticationCode* mac,
void Randpool::randomize(byte out[], u32bit length)
{
if(!is_seeded())
- throw PRNG_Unseeded(name());
+ {
+ reseed();
+
+ if(!is_seeded())
+ throw PRNG_Unseeded(name());
+ }
update_buffer();
while(length)
@@ -66,18 +62,16 @@ void Randpool::update_buffer()
break;
store_be(timestamp, counter + 4);
- SecureVector<byte> mac_val = randpool_prf(mac, GEN_OUTPUT,
- counter, counter.size());
+ mac->update(static_cast<byte>(GEN_OUTPUT));
+ mac->update(counter, counter.size());
+ SecureVector<byte> mac_val = mac->final();
for(u32bit j = 0; j != mac_val.size(); ++j)
buffer[j % buffer.size()] ^= mac_val[j];
cipher->encrypt(buffer);
if(counter[0] % ITERATIONS_BEFORE_RESEED == 0)
- {
mix_pool();
- update_buffer();
- }
}
/*************************************************
@@ -87,8 +81,13 @@ void Randpool::mix_pool()
{
const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
- mac->set_key(randpool_prf(mac, MAC_KEY, pool, pool.size()));
- cipher->set_key(randpool_prf(mac, CIPHER_KEY, pool, pool.size()));
+ mac->update(static_cast<byte>(MAC_KEY));
+ mac->update(pool, pool.size());
+ mac->set_key(mac->final());
+
+ mac->update(static_cast<byte>(CIPHER_KEY));
+ mac->update(pool, pool.size());
+ cipher->set_key(mac->final());
xor_buf(pool, buffer, BLOCK_SIZE);
cipher->encrypt(pool);
@@ -99,20 +98,54 @@ void Randpool::mix_pool()
xor_buf(this_block, previous_block, BLOCK_SIZE);
cipher->encrypt(this_block);
}
+
+ update_buffer();
}
/*************************************************
-* Add entropy to the internal state *
+* Reseed the internal state *
*************************************************/
-void Randpool::add_randomness(const byte data[], u32bit length)
+void Randpool::reseed()
{
- u32bit this_entropy = entropy_estimate(data, length);
- entropy += std::min(this_entropy, 8*mac->OUTPUT_LENGTH);
- entropy = std::min(entropy, 8 * pool.size());
+ SecureVector<byte> buffer(1024);
+ u32bit gathered_entropy = 0;
+
+ for(u32bit j = 0; j != entropy_sources.size(); ++j)
+ {
+ u32bit got = entropy_sources[j]->slow_poll(buffer, buffer.size());
+
+ mac->update(buffer, got);
+
+ gathered_entropy += entropy_estimate(buffer, got);
+ if(gathered_entropy > 512)
+ break;
+ }
- SecureVector<byte> mac_val = randpool_prf(mac, USER_INPUT, data, length);
+ SecureVector<byte> mac_val = mac->final();
xor_buf(pool, mac_val, mac_val.size());
mix_pool();
+
+ entropy += gathered_entropy;
+ }
+
+/*************************************************
+* Add user-supplied entropy *
+*************************************************/
+void Randpool::add_entropy(const byte input[], u32bit length)
+ {
+ SecureVector<byte> mac_val = mac->process(input, length);
+ xor_buf(pool, mac_val, mac_val.size());
+ mix_pool();
+
+ entropy += entropy_estimate(input, length);
+ }
+
+/*************************************************
+* Add another entropy source to the list *
+*************************************************/
+void Randpool::add_entropy_source(EntropySource* src)
+ {
+ entropy_sources.push_back(src);
}
/*************************************************
@@ -120,7 +153,7 @@ void Randpool::add_randomness(const byte data[], u32bit length)
*************************************************/
bool Randpool::is_seeded() const
{
- return (entropy >= 256);
+ return (entropy >= 384);
}
/*************************************************
@@ -149,7 +182,7 @@ std::string Randpool::name() const
*************************************************/
Randpool::Randpool(const std::string& cipher_name,
const std::string& mac_name) :
- ITERATIONS_BEFORE_RESEED(8), POOL_BLOCKS(32)
+ ITERATIONS_BEFORE_RESEED(128), POOL_BLOCKS(32)
{
cipher = get_block_cipher(cipher_name);
mac = get_mac(mac_name);
@@ -171,8 +204,6 @@ Randpool::Randpool(const std::string& cipher_name,
pool.create(POOL_BLOCKS * BLOCK_SIZE);
counter.create(12);
entropy = 0;
-
- mix_pool();
}
/*************************************************
@@ -182,6 +213,10 @@ Randpool::~Randpool()
{
delete cipher;
delete mac;
+
+ std::for_each(entropy_sources.begin(), entropy_sources.end(),
+ del_fun<EntropySource>());
+
entropy = 0;
}