summaryrefslogtreecommitdiff
path: root/randpool.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2017-08-01 18:53:31 -0400
committerJeffrey Walton <noloader@gmail.com>2017-08-01 18:53:31 -0400
commit02e3a794443ae6d985ddf881d52a87bae1e7cd6f (patch)
tree300a4938ce461f6dbb2768258023989a7c770d88 /randpool.cpp
parent2171a3a3792c43f75e96b8376cadad4836dd1929 (diff)
downloadcryptopp-git-02e3a794443ae6d985ddf881d52a87bae1e7cd6f.tar.gz
Add OldRandomPool class (Issue 452)
RandomPool used to be a PGP-style deterministic generator and folks used it as a key generation function. At Crypto++ 5.5 the design changed to harden it agianst rollback attacks. The design change resulted in an upgrade barrier. That is, some folks are stuck at Crypto++ 4.2 or Crypto++ 5.2 because they must interoperate with existing software. Below is the test program we used for the test vector. It was run against Crypto++ 5.4. RandomPool prng; SecByteBlock seed(0x00, 384), result(64); prng.Put(seed, seed.size()); prng.GenerateBlock(result, result.size()); HexEncoder encoder(new FileSink(std::cout)); std::cout << "RandomPool: "; encoder.Put(result, sizeof(result)); std::cout << std::endl;
Diffstat (limited to 'randpool.cpp')
-rw-r--r--randpool.cpp90
1 files changed, 89 insertions, 1 deletions
diff --git a/randpool.cpp b/randpool.cpp
index a7d2efdf..a904c6eb 100644
--- a/randpool.cpp
+++ b/randpool.cpp
@@ -12,7 +12,13 @@
#include "aes.h"
#include "sha.h"
#include "hrtimer.h"
-#include <time.h>
+#include "trap.h"
+
+// OldRandomPool
+#include "mdc.h"
+#include "modes.h"
+
+#include <ctime>
NAMESPACE_BEGIN(CryptoPP)
@@ -69,6 +75,88 @@ void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &targ
}
}
+// OldRandomPool is provided for backwards compatibility for a migration path
+typedef MDC<SHA1> OldRandomPoolCipher;
+
+OldRandomPool::OldRandomPool(unsigned int poolSize)
+ : pool(poolSize), key(OldRandomPoolCipher::DEFAULT_KEYLENGTH), addPos(0), getPos(poolSize)
+{
+ CRYPTOPP_ASSERT(poolSize > key.size());
+ memset(pool, 0, poolSize);
+ memset(key, 0, key.size());
+}
+
+void OldRandomPool::Stir()
+{
+ CFB_Mode<OldRandomPoolCipher>::Encryption cipher;
+
+ for (int i=0; i<2; i++)
+ {
+ cipher.SetKeyWithIV(key, key.size(), pool.end()-cipher.IVSize());
+ cipher.ProcessString(pool, pool.size());
+ memcpy(key, pool, key.size());
+ }
+
+ addPos = 0;
+ getPos = key.size();
+}
+
+size_t OldRandomPool::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
+{
+ size_t t;
+
+ while (length > (t = pool.size() - addPos))
+ {
+ xorbuf(pool+addPos, inString, t);
+ inString += t;
+ length -= t;
+ Stir();
+ }
+
+ if (length)
+ {
+ xorbuf(pool+addPos, inString, length);
+ addPos += length;
+ getPos = pool.size(); // Force stir on get
+ }
+
+ return 0;
+}
+
+size_t OldRandomPool::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
+{
+ if (!blocking)
+ throw NotImplemented("OldRandomPool: nonblocking transfer is not implemented by this object");
+
+ lword size = transferBytes;
+
+ while (size > 0)
+ {
+ if (getPos == pool.size())
+ Stir();
+ size_t t = UnsignedMin(pool.size() - getPos, size);
+ target.ChannelPut(channel, pool+getPos, t);
+ size -= t;
+ getPos += t;
+ }
+
+ return 0;
+}
+
+byte OldRandomPool::GenerateByte()
+{
+ if (getPos == pool.size())
+ Stir();
+
+ return pool[getPos++];
+}
+
+void OldRandomPool::GenerateBlock(byte *outString, size_t size)
+{
+ ArraySink sink(outString, size);
+ TransferTo(sink, size);
+}
+
NAMESPACE_END
#endif