summaryrefslogtreecommitdiff
path: root/rng.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2007-05-04 15:04:58 +0000
committerweidai <weidai11@users.noreply.github.com>2007-05-04 15:04:58 +0000
commitf9261eb10740446fb65ea1431d42c3b9c6926ff3 (patch)
treeaf7086b6bdb722b9a90c1abe0dd994166f32040b /rng.cpp
parentc09618a557b50da44ddac06ccb3d24a71f9484f4 (diff)
downloadcryptopp-git-f9261eb10740446fb65ea1431d42c3b9c6926ff3.tar.gz
reduce risk of random number reuse after VM rollback
Diffstat (limited to 'rng.cpp')
-rw-r--r--rng.cpp58
1 files changed, 35 insertions, 23 deletions
diff --git a/rng.cpp b/rng.cpp
index 711f9a01..fb52a2bb 100644
--- a/rng.cpp
+++ b/rng.cpp
@@ -3,6 +3,7 @@
#include "pch.h"
#include "rng.h"
+#include "fips140.h"
#include <time.h>
#include <math.h>
@@ -35,19 +36,22 @@ const word16 LC_RNG::a=16807;
const word16 LC_RNG::r=2836;
#endif
-byte LC_RNG::GenerateByte()
+void LC_RNG::GenerateBlock(byte *output, size_t size)
{
- word32 hi = seed/q;
- word32 lo = seed%q;
+ while (size--)
+ {
+ word32 hi = seed/q;
+ word32 lo = seed%q;
- long test = a*lo - r*hi;
+ long test = a*lo - r*hi;
- if (test > 0)
- seed = test;
- else
- seed = test+ m;
+ if (test > 0)
+ seed = test;
+ else
+ seed = test+ m;
- return (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
+ *output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
+ }
}
// ********************************************************
@@ -59,24 +63,26 @@ X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *determini
S(cipher->BlockSize()),
dtbuf(S),
randseed(seed, S),
- randbuf(S),
- randbuf_counter(0),
+ m_lastBlock(S),
m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0)
{
if (!deterministicTimeVector)
{
time_t tstamp1 = time(0);
- xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
+ xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S));
cipher->ProcessBlock(dtbuf);
clock_t tstamp2 = clock();
- xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
+ xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S));
cipher->ProcessBlock(dtbuf);
}
+
+ // for FIPS 140-2
+ GenerateBlock(m_lastBlock, S);
}
-byte X917RNG::GenerateByte()
+void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
{
- if (randbuf_counter==0)
+ while (size > 0)
{
// calculate new enciphered timestamp
if (m_deterministicTimeVector.size())
@@ -86,8 +92,10 @@ byte X917RNG::GenerateByte()
}
else
{
- clock_t tstamp = clock();
- xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
+ clock_t c = clock();
+ xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S));
+ time_t t = time(NULL);
+ xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S));
cipher->ProcessBlock(dtbuf);
}
@@ -95,16 +103,20 @@ byte X917RNG::GenerateByte()
xorbuf(randseed, dtbuf, S);
// generate a new block of random bytes
- cipher->ProcessBlock(randseed, randbuf);
+ cipher->ProcessBlock(randseed);
+ if (memcmp(m_lastBlock, randseed, S) == 0)
+ throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
+
+ // output random bytes
+ size_t len = UnsignedMin(size, S);
+ target.ChannelPut(channel, randseed, len);
+ size -= len;
// compute new seed vector
- for (int i=0; i<S; i++)
- randseed[i] = randbuf[i] ^ dtbuf[i];
+ memcpy(m_lastBlock, randseed, S);
+ xorbuf(randseed, dtbuf, S);
cipher->ProcessBlock(randseed);
-
- randbuf_counter=S;
}
- return(randbuf[S-randbuf_counter--]);
}
#endif