1
1
// randpool.cpp - written and placed in the public domain by Wei Dai
2
// The algorithm in this module comes from PGP's randpool.c
2
// RandomPool used to follow the design of randpool in PGP 2.6.x,
3
// but as of version 5.5 it has been redesigned to reduce the risk
4
// of reusing random numbers after state rollback (which may occur
5
// when running in a virtual machine like VMware).
6
9
#ifndef CRYPTOPP_IMPORTS
8
11
#include "randpool.h"
17
#if GCC_DIAGNOSTIC_AWARE
18
# pragma GCC diagnostic ignored "-Wunused-value"
19
# pragma GCC diagnostic ignored "-Wunused-variable"
13
22
NAMESPACE_BEGIN(CryptoPP)
15
typedef MDC<SHA> RandomPoolCipher;
17
RandomPool::RandomPool(unsigned int poolSize)
18
: pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
20
assert(poolSize > key.size());
24
memset(pool, 0, poolSize);
25
memset(key, 0, key.size());
28
void RandomPool::Stir()
30
CFB_Mode<RandomPoolCipher>::Encryption cipher;
32
for (int i=0; i<2; i++)
34
cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
35
cipher.ProcessString(pool, pool.size());
36
memcpy(key, pool, key.size());
43
size_t RandomPool::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
47
while (length > (t = pool.size() - addPos))
49
xorbuf(pool+addPos, inString, t);
57
xorbuf(pool+addPos, inString, length);
59
getPos = pool.size(); // Force stir on get
65
size_t RandomPool::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
68
throw NotImplemented("RandomPool: nonblocking transfer is not implemented by this object");
70
lword size = transferBytes;
74
if (getPos == pool.size())
76
size_t t = UnsignedMin(pool.size() - getPos, size);
77
target.ChannelPut(channel, pool+getPos, t);
85
byte RandomPool::GenerateByte()
87
if (getPos == pool.size())
90
return pool[getPos++];
93
void RandomPool::GenerateBlock(byte *outString, size_t size)
95
ArraySink sink(outString, size);
96
TransferTo(sink, size);
24
RandomPool::RandomPool()
25
: m_pCipher(new AES::Encryption), m_keySet(false)
27
memset(m_key, 0, m_key.SizeInBytes());
28
memset(m_seed, 0, m_seed.SizeInBytes());
31
void RandomPool::IncorporateEntropy(const byte *input, size_t length)
34
hash.Update(m_key, 32);
35
hash.Update(input, length);
40
void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
45
m_pCipher->SetKey(m_key, 32);
48
TimerWord tw = timer.GetCurrentTimerValue();
49
CRYPTOPP_COMPILE_ASSERT(sizeof(tw) <= 16);
50
*(TimerWord *)m_seed.data() += tw;
52
time_t t = time(NULL);
53
CRYPTOPP_COMPILE_ASSERT(sizeof(t) <= 8);
54
*(time_t *)(m_seed.data()+8) += t;
58
m_pCipher->ProcessBlock(m_seed);
59
size_t len = UnsignedMin(16, size);
60
target.ChannelPut(channel, m_seed, len);