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 for (int i=0; i<2; i++)
00028 {
00029 RandomPoolCipher cipher(key);
00030 CFBEncryption cfb(cipher, pool+pool.size-cipher.BlockSize());
00031 cfb.ProcessString(pool, pool.size);
00032 memcpy(key, pool, key.size);
00033 }
00034
00035 addPos = 0;
00036 getPos = key.size;
00037 }
00038
00039 void RandomPool::Put(byte inByte)
00040 {
00041 if (addPos == pool.size)
00042 Stir();
00043
00044 pool[addPos++] ^= inByte;
00045 getPos = pool.size;
00046 }
00047
00048 void RandomPool::Put(const byte *inString, unsigned int length)
00049 {
00050 unsigned t;
00051
00052 while (length > (t = pool.size - addPos))
00053 {
00054 xorbuf(pool+addPos, inString, t);
00055 inString += t;
00056 length -= t;
00057 Stir();
00058 }
00059
00060 if (length)
00061 {
00062 xorbuf(pool+addPos, inString, length);
00063 addPos += length;
00064 getPos = pool.size;
00065 }
00066 }
00067
00068 byte RandomPool::GenerateByte()
00069 {
00070 if (getPos == pool.size)
00071 Stir();
00072
00073 return pool[getPos++];
00074 }
00075
00076 void RandomPool::GenerateBlock(byte *outString, unsigned int size)
00077 {
00078 unsigned t;
00079
00080 while (size > (t = pool.size - getPos))
00081 {
00082 memcpy(outString, pool+getPos, t);
00083 outString += t;
00084 size -= t;
00085 Stir();
00086 }
00087
00088 if (size)
00089 {
00090 memcpy(outString, pool+getPos, size);
00091 getPos += size;
00092 }
00093 }
00094
00095 NAMESPACE_END