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