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 size_t RandomPool::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00044 {
00045 size_t 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 size_t RandomPool::TransferTo2(BufferedTransformation &target, lword &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 lword size = transferBytes;
00071
00072 while (size > 0)
00073 {
00074 if (getPos == pool.size())
00075 Stir();
00076 size_t t = UnsignedMin(pool.size() - getPos, size);
00077 target.ChannelPut(channel, pool+getPos, t);
00078 size -= t;
00079 getPos += t;
00080 }
00081
00082 return 0;
00083 }
00084
00085 byte RandomPool::GenerateByte()
00086 {
00087 if (getPos == pool.size())
00088 Stir();
00089
00090 return pool[getPos++];
00091 }
00092
00093 void RandomPool::GenerateBlock(byte *outString, size_t size)
00094 {
00095 ArraySink sink(outString, size);
00096 TransferTo(sink, size);
00097 }
00098
00099 NAMESPACE_END
00100
00101 #endif