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