aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-06-07 15:55:54 +0000
committerlloyd <[email protected]>2008-06-07 15:55:54 +0000
commit4cb905ce8bf113516ea9885909fe5a832aeddf5d (patch)
treed682d86d28d4379f91317e4cb88d4b79e588de7f
parent4e3ed1be76906bcd3440dd3fbf78569a0d684dfc (diff)
Change how the ANSI X9.31 generator tells that it is seeded. Previously,
it was seeded if and only if the underlying PRNG was seeded. However if the PRNG always returned as being seeded, we would never generate a V value, etc (leaving them at the default zero). This would not occur with any of Botan's built in PRNGs since their implementations require that add_randomness be called at least once before is_seeded will return true. However this is not an invariant of the general RandomNumberGenerator interface. Now, the X9.31 PRNG is only seeded after it has a) detected that the PRNG is seeded, and b) generated a new random key and V vector.
-rw-r--r--src/x931_rng.cpp26
1 files changed, 11 insertions, 15 deletions
diff --git a/src/x931_rng.cpp b/src/x931_rng.cpp
index 94d5f9247..99d0730bd 100644
--- a/src/x931_rng.cpp
+++ b/src/x931_rng.cpp
@@ -21,15 +21,15 @@ void ANSI_X931_RNG::randomize(byte out[], u32bit length) throw(PRNG_Unseeded)
while(length)
{
+ if(position == R.size())
+ update_buffer();
+
const u32bit copied = std::min(length, R.size() - position);
copy_mem(out, R + position, copied);
out += copied;
length -= copied;
position += copied;
-
- if(position == R.size())
- update_buffer();
}
}
@@ -38,17 +38,15 @@ void ANSI_X931_RNG::randomize(byte out[], u32bit length) throw(PRNG_Unseeded)
*************************************************/
void ANSI_X931_RNG::update_buffer()
{
- const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
-
- SecureVector<byte> DT(BLOCK_SIZE);
+ SecureVector<byte> DT(cipher->BLOCK_SIZE);
prng->randomize(DT, DT.size());
cipher->encrypt(DT);
- xor_buf(R, V, DT, BLOCK_SIZE);
+ xor_buf(R, V, DT, cipher->BLOCK_SIZE);
cipher->encrypt(R);
- xor_buf(V, R, DT, BLOCK_SIZE);
+ xor_buf(V, R, DT, cipher->BLOCK_SIZE);
cipher->encrypt(V);
position = 0;
@@ -61,12 +59,14 @@ void ANSI_X931_RNG::add_randomness(const byte data[], u32bit length)
{
prng->add_entropy(data, length);
- if(is_seeded())
+ if(prng->is_seeded())
{
SecureVector<byte> key(cipher->MAXIMUM_KEYLENGTH);
prng->randomize(key, key.size());
cipher->set_key(key, key.size());
+ if(V.size() != cipher->BLOCK_SIZE)
+ V.create(cipher->BLOCK_SIZE);
prng->randomize(V, V.size());
update_buffer();
@@ -78,7 +78,7 @@ void ANSI_X931_RNG::add_randomness(const byte data[], u32bit length)
*************************************************/
bool ANSI_X931_RNG::is_seeded() const
{
- return prng->is_seeded();
+ return V.has_items();
}
/*************************************************
@@ -114,11 +114,7 @@ ANSI_X931_RNG::ANSI_X931_RNG(const std::string& cipher_name,
prng = prng_ptr;
cipher = get_block_cipher(cipher_name);
- const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
-
- V.create(BLOCK_SIZE);
- R.create(BLOCK_SIZE);
-
+ R.create(cipher->BLOCK_SIZE);
position = 0;
}