00001
00002
00003
00004 #include "pch.h"
00005 #include "randpool.h"
00006 #include "mdc.h"
00007 #include "sha.h"
00008 #include "modes.h"
00009
00010 NAMESPACE_BEGIN(CryptoPP)
00011
00012 typedef MDC<SHA> RandomPoolCipher;
00013
00014 RandomPool::RandomPool(unsigned int poolSize)
00015 : pool(poolSize), key(RandomPoolCipher::DEFAULT_KEYLENGTH)
00016 {
00017 assert(poolSize > key.size());
00018
00019 addPos=0;
00020 getPos=poolSize;
00021 memset(pool, 0, poolSize);
00022 memset(key, 0, key.size());
00023 }
00024
00025 void RandomPool::Stir()
00026 {
00027 CFB_Mode<RandomPoolCipher>::Encryption cipher;
00028
00029 for (int i=0; i<2; i++)
00030 {
00031 cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
00032 cipher.ProcessString(pool, pool.size());
00033 memcpy(key, pool, key.size());
00034 }
00035
00036 addPos = 0;
00037 getPos = key.size();
00038 }
00039
00040 unsigned int RandomPool::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00041 {
00042 unsigned t;
00043
00044 while (length > (t = pool.size() - addPos))
00045 {
00046 xorbuf(pool+addPos, inString, t);
00047 inString += t;
00048 length -= t;
00049 Stir();
00050 }
00051
00052 if (length)
00053 {
00054 xorbuf(pool+addPos, inString, length);
00055 addPos += length;
00056 getPos = pool.size();
00057 }
00058
00059 return 0;
00060 }
00061
00062 unsigned int RandomPool::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00063 {
00064 if (!blocking)
00065 throw NotImplemented("RandomPool: nonblocking transfer is not implemented by this object");
00066
00067 unsigned int t;
00068 unsigned long size = transferBytes;
00069
00070 while (size > (t = pool.size() - getPos))
00071 {
00072 target.ChannelPut(channel, pool+getPos, t);
00073 size -= t;
00074 Stir();
00075 }
00076
00077 if (size)
00078 {
00079 target.ChannelPut(channel, pool+getPos, size);
00080 getPos += size;
00081 }
00082
00083 return 0;
00084 }
00085
00086 byte RandomPool::GenerateByte()
00087 {
00088 if (getPos == pool.size())
00089 Stir();
00090
00091 return pool[getPos++];
00092 }
00093
00094 void RandomPool::GenerateBlock(byte *outString, unsigned int size)
00095 {
00096 ArraySink sink(outString, size);
00097 TransferTo(sink, size);
00098 }
00099
00100 NAMESPACE_END