summaryrefslogtreecommitdiff
path: root/osrng.h
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
commitb21162cf8e06f40baa1f58be6a8c17435cebc34d (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /osrng.h
downloadcryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'osrng.h')
-rw-r--r--osrng.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/osrng.h b/osrng.h
new file mode 100644
index 0000000..3a40560
--- /dev/null
+++ b/osrng.h
@@ -0,0 +1,157 @@
+#ifndef CRYPTOPP_OSRNG_H
+#define CRYPTOPP_OSRNG_H
+
+#include "config.h"
+
+#ifdef OS_RNG_AVAILABLE
+
+#include "randpool.h"
+#include "rng.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+//! Exception class for Operating-System Random Number Generator.
+class OS_RNG_Err : public Exception
+{
+public:
+ OS_RNG_Err(const std::string &operation);
+};
+
+#ifdef NONBLOCKING_RNG_AVAILABLE
+
+#ifdef CRYPTOPP_WIN32_AVAILABLE
+class MicrosoftCryptoProvider
+{
+public:
+ MicrosoftCryptoProvider();
+ ~MicrosoftCryptoProvider();
+#if defined(_WIN64)
+ typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h>
+#else
+ typedef unsigned long ProviderHandle;
+#endif
+ ProviderHandle GetProviderHandle() const {return m_hProvider;}
+private:
+ ProviderHandle m_hProvider;
+};
+#endif
+
+//! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
+class NonblockingRng : public RandomNumberGenerator
+{
+public:
+ NonblockingRng();
+ ~NonblockingRng();
+ byte GenerateByte();
+ void GenerateBlock(byte *output, unsigned int size);
+
+protected:
+#ifdef CRYPTOPP_WIN32_AVAILABLE
+# ifndef WORKAROUND_MS_BUG_Q258000
+ MicrosoftCryptoProvider m_Provider;
+# endif
+#else
+ int m_fd;
+#endif
+};
+
+#endif
+
+#ifdef BLOCKING_RNG_AVAILABLE
+
+//! encapsulate /dev/random
+class BlockingRng : public RandomNumberGenerator
+{
+public:
+ BlockingRng();
+ ~BlockingRng();
+ byte GenerateByte();
+ void GenerateBlock(byte *output, unsigned int size);
+
+protected:
+ int m_fd;
+};
+
+#endif
+
+void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
+
+//! Automaticly Seeded Randomness Pool
+/*! This class seeds itself using an operating system provided RNG. */
+class AutoSeededRandomPool : public RandomPool
+{
+public:
+ //! blocking will be ignored if the prefered RNG isn't available
+ explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
+ {Reseed(blocking, seedSize);}
+ void Reseed(bool blocking = false, unsigned int seedSize = 32);
+};
+
+//! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
+template <class BLOCK_CIPHER>
+class AutoSeededX917RNG : public RandomNumberGenerator
+{
+public:
+ //! blocking will be ignored if the prefered RNG isn't available
+ explicit AutoSeededX917RNG(bool blocking = false)
+ {Reseed(blocking);}
+ void Reseed(bool blocking = false);
+
+ byte GenerateByte();
+
+private:
+ member_ptr<RandomNumberGenerator> m_rng;
+ SecByteBlock m_lastBlock;
+ bool m_isDifferent;
+ unsigned int m_counter;
+};
+
+template <class BLOCK_CIPHER>
+void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
+{
+ SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
+ const byte *key;
+ do
+ {
+ OS_GenerateRandomBlock(blocking, seed, seed.size());
+ key = seed + BLOCK_CIPHER::BLOCKSIZE;
+ } // check that seed and key don't have same value
+ while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
+ m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH), seed));
+
+ if (FIPS_140_2_ComplianceEnabled())
+ {
+ m_lastBlock.resize(16);
+ m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
+ m_counter = 0;
+ m_isDifferent = false;
+ }
+}
+
+template <class BLOCK_CIPHER>
+byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
+{
+ byte b = m_rng->GenerateByte();
+
+ if (FIPS_140_2_ComplianceEnabled())
+ {
+ m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
+ m_lastBlock[m_counter] = b;
+ ++m_counter;
+ if (m_counter == m_lastBlock.size())
+ {
+ if (!m_isDifferent)
+ throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
+ m_counter = 0;
+ m_isDifferent = false;
+ }
+ }
+
+ return b;
+}
+
+NAMESPACE_END
+
+#endif
+
+#endif