diff --git a/randpool.cpp b/randpool.cpp index 39afd72f..1813da54 100644 --- a/randpool.cpp +++ b/randpool.cpp @@ -86,6 +86,11 @@ OldRandomPool::OldRandomPool(unsigned int poolSize) ::memset(key, 0, key.size()); } +void OldRandomPool::IncorporateEntropy(const byte *input, size_t length) +{ + OldRandomPool::Put(input, length); +} + void OldRandomPool::Stir() { CFB_Mode::Encryption cipher; diff --git a/randpool.h b/randpool.h index 37dda408..11029f58 100644 --- a/randpool.h +++ b/randpool.h @@ -33,11 +33,11 @@ NAMESPACE_BEGIN(CryptoPP) //! AES-256 to produce the stream. Entropy is stirred in using SHA-256. //! \details RandomPool used to follow the design of randpool in PGP 2.6.x. At version 5.5 //! RandomPool was redesigned to reduce the risk of reusing random numbers after state -//! rollback (which may occur when running in a virtual machine like VMware or a hosted -//! environment). +//! rollback, which may occur when running in a virtual machine like VMware or a hosted +//! environment. //! \details If you need the pre-Crypto++ 5.5 generator then use OldRandomPool class. You -//! should migrate away from OldRandomPool at the earliest opportunity. Use RandomPool -//! or AutoSeededRandomPool instead. +//! should migrate away from OldRandomPool at the earliest opportunity. +//! \sa OldRandomPool //! \since Crypto++ 4.0 (PGP 2.6.x style), Crypto++ 5.5 (AES-256 based) class CRYPTOPP_DLL RandomPool : public RandomNumberGenerator, public NotCopyable { @@ -49,10 +49,6 @@ public: void IncorporateEntropy(const byte *input, size_t length); void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); - // for backwards compatibility. use RandomNumberSource, RandomNumberStore, and - // RandomNumberSink for other BufferTransformation functionality - void Put(const byte *input, size_t length) {IncorporateEntropy(input, length);} - private: FixedSizeAlignedSecBlock m_seed; FixedSizeAlignedSecBlock m_key; @@ -64,11 +60,17 @@ private: //! \brief Randomness Pool based on PGP 2.6.x with MDC //! \details If you need the pre-Crypto++ 5.5 generator then use OldRandomPool class. The //! OldRandomPool class is always available so you dont need to define -//! CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY. However, you should migrate away from -//! OldRandomPool at the earliest opportunity. Use RandomPool or AutoSeededRandomPool instead. +//! CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY. OldRandomPool also provides the modern +//! interface, including CanIncorporateEntropy, IncorporateEntropy and +//! GenerateIntoBufferedTransformation. +//! \details You should migrate away from OldRandomPool at the earliest opportunity. Use a +//! modern random number generator or key derivation function, like AutoSeededRandomPool or +//! HKDF. //! \deprecated This class uses an old style PGP 2.6.x with MDC. The generator risks reusing -//! random random numbers after state rollback. Migrate to RandomPool or AutoSeededRandomPool +//! random random numbers after state rollback. You should migrate away from OldRandomPool //! at the earliest opportunity. +//! HKDF. +//! \sa RandomPool, AutoSeededRandomPool, HKDF, P1363_KDF2, PKCS12_PBKDF, PKCS5_PBKDF2_HMAC //! \since Crypto++ 6.0 (PGP 2.6.x style) class CRYPTOPP_DLL OldRandomPool : public RandomNumberGenerator, public Bufferless @@ -79,6 +81,11 @@ public: //! \details poolSize must be greater than 16 OldRandomPool(unsigned int poolSize=384); + // RandomNumberGenerator interface (Crypto++ 5.5 and above) + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length); + + // BufferedTransformation interface (Crypto++ 5.4 and below) size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); bool AnyRetrievable() const {return true;} diff --git a/validat1.cpp b/validat1.cpp index 2cf5bfa0..cc72530a 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -264,14 +264,14 @@ bool TestSettings() // Don't assert the alignment of testvals. That's what this test is for. byte testvals[10] = {1,2,2,3,3,3,3,2,2,1}; if (*(word32 *)(void *)(testvals+3) == 0x03030303 && *(word64 *)(void *)(testvals+1) == W64LIT(0x0202030303030202)) - std::cout << "passed: Your machine allows unaligned data access.\n"; + std::cout << "passed: Unaligned data access (CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS).\n"; else { std::cout << "FAILED: Unaligned data access gave incorrect results.\n"; pass = false; } #else - std::cout << "passed: CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is not defined. Will restrict to aligned data access.\n"; + std::cout << "passed: Aligned data access (no CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS).\n"; #endif if (sizeof(byte) == 1) @@ -339,7 +339,6 @@ bool TestSettings() std::cout << std::endl; #ifdef CRYPTOPP_CPUID_AVAILABLE - bool hasMMX = HasMMX(); bool hasISSE = HasISSE(); bool hasSSE2 = HasSSE2(); bool hasSSSE3 = HasSSSE3(); @@ -347,7 +346,7 @@ bool TestSettings() bool isP4 = IsP4(); int cacheLineSize = GetCacheLineSize(); - if ((isP4 && (!hasMMX || !hasSSE2)) || (hasSSE2 && !hasMMX) || (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize))) + if (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize)) { std::cout << "FAILED: "; pass = false; @@ -355,7 +354,7 @@ bool TestSettings() else std::cout << "passed: "; - std::cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", hasSSE4 == " << hasSSE4; + std::cout << "hasISSE == " << hasISSE << "hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", hasSSE4 == " << hasSSE4; std::cout << ", hasAESNI == " << HasAESNI() << ", hasCLMUL == " << HasCLMUL() << ", hasRDRAND == " << HasRDRAND() << ", hasRDSEED == " << HasRDSEED(); std::cout << ", hasSHA == " << HasSHA() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize << std::endl; @@ -723,7 +722,7 @@ bool TestRandomPool() // with it in 2017. The missing functionality was a barrier to upgrades. std::cout << "\nTesting OldRandomPool generator...\n\n"; { - OldRandomPool prng; + OldRandomPool old1; static const unsigned int ENTROPY_SIZE = 32; // https://github.com/weidai11/cryptopp/issues/452 @@ -735,9 +734,9 @@ bool TestRandomPool() }; SecByteBlock seed(0x00, 384); - prng.Put(seed, seed.size()); + old1.Put(seed, seed.size()); - prng.GenerateBlock(result, sizeof(result)); + old1.GenerateBlock(result, sizeof(result)); fail = (0 != ::memcmp(result, expected, sizeof(expected))); pass &= !fail; @@ -745,8 +744,23 @@ bool TestRandomPool() std::cout << "FAILED:"; else std::cout << "passed:"; - std::cout << " Expected sequence from PGP-style RandomPool (2007 version)\n"; + std::cout << " Expected sequence from PGP-style RandomPool (circa 2007)\n"; + OldRandomPool old2; + old2.IncorporateEntropy(seed, seed.size()); + + ArraySink sink(result, sizeof(result)); + old2.GenerateIntoBufferedTransformation(sink, DEFAULT_CHANNEL, sizeof(result)); + fail = (0 != ::memcmp(result, expected, sizeof(expected))); + + pass &= !fail; + if (fail) + std::cout << "FAILED:"; + else + std::cout << "passed:"; + std::cout << " Expected sequence from PGP-style RandomPool new interface (circa 2007)\n"; + + OldRandomPool prng; MeterFilter meter(new Redirector(TheBitBucket())); RandomNumberSource test(prng, 100000, true, new Deflator(new Redirector(meter)));