Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

osrng.h

00001 #ifndef CRYPTOPP_OSRNG_H
00002 #define CRYPTOPP_OSRNG_H
00003 
00004 #include "config.h"
00005 
00006 #ifdef OS_RNG_AVAILABLE
00007 
00008 #include "randpool.h"
00009 #include "rng.h"
00010 #include "des.h"
00011 
00012 NAMESPACE_BEGIN(CryptoPP)
00013 
00014 //! Exception class for Operating-System Random Number Generator.
00015 class CRYPTOPP_DLL OS_RNG_Err : public Exception
00016 {
00017 public:
00018         OS_RNG_Err(const std::string &operation);
00019 };
00020 
00021 #ifdef NONBLOCKING_RNG_AVAILABLE
00022 
00023 #ifdef CRYPTOPP_WIN32_AVAILABLE
00024 class CRYPTOPP_DLL MicrosoftCryptoProvider
00025 {
00026 public:
00027         MicrosoftCryptoProvider();
00028         ~MicrosoftCryptoProvider();
00029 #if defined(_WIN64)
00030         typedef unsigned __int64 ProviderHandle;        // type HCRYPTPROV, avoid #include <windows.h>
00031 #else
00032         typedef unsigned long ProviderHandle;
00033 #endif
00034         ProviderHandle GetProviderHandle() const {return m_hProvider;}
00035 private:
00036         ProviderHandle m_hProvider;
00037 };
00038 #endif
00039 
00040 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
00041 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
00042 {
00043 public:
00044         NonblockingRng();
00045         ~NonblockingRng();
00046         byte GenerateByte();
00047         void GenerateBlock(byte *output, unsigned int size);
00048 
00049 protected:
00050 #ifdef CRYPTOPP_WIN32_AVAILABLE
00051 #       ifndef WORKAROUND_MS_BUG_Q258000
00052                 MicrosoftCryptoProvider m_Provider;
00053 #       endif
00054 #else
00055         int m_fd;
00056 #endif
00057 };
00058 
00059 #endif
00060 
00061 #ifdef BLOCKING_RNG_AVAILABLE
00062 
00063 //! encapsulate /dev/random
00064 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
00065 {
00066 public:
00067         BlockingRng();
00068         ~BlockingRng();
00069         byte GenerateByte();
00070         void GenerateBlock(byte *output, unsigned int size);
00071 
00072 protected:
00073         int m_fd;
00074 };
00075 
00076 #endif
00077 
00078 CRYPTOPP_DLL void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
00079 
00080 //! Automaticly Seeded Randomness Pool
00081 /*! This class seeds itself using an operating system provided RNG. */
00082 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
00083 {
00084 public:
00085         //! blocking will be ignored if the prefered RNG isn't available
00086         explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
00087                 {Reseed(blocking, seedSize);}
00088         void Reseed(bool blocking = false, unsigned int seedSize = 32);
00089 };
00090 
00091 //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
00092 template <class BLOCK_CIPHER>
00093 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
00094 {
00095 public:
00096         //! blocking will be ignored if the prefered RNG isn't available
00097         explicit AutoSeededX917RNG(bool blocking = false)
00098                 {Reseed(blocking);}
00099         void Reseed(bool blocking = false);
00100         // exposed for testing
00101         void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector);
00102 
00103         byte GenerateByte();
00104 
00105 private:
00106         member_ptr<RandomNumberGenerator> m_rng;
00107         SecByteBlock m_lastBlock;
00108         bool m_isDifferent;
00109         unsigned int m_counter;
00110 };
00111 
00112 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<DES_EDE3>;
00113 
00114 template <class BLOCK_CIPHER>
00115 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector)
00116 {
00117         m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00118 
00119         if (FIPS_140_2_ComplianceEnabled())
00120         {
00121                 m_lastBlock.resize(16);
00122                 m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
00123                 m_counter = 0;
00124                 m_isDifferent = false;
00125         }
00126 }
00127 
00128 template <class BLOCK_CIPHER>
00129 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
00130 {
00131         SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00132         const byte *key;
00133         do
00134         {
00135                 OS_GenerateRandomBlock(blocking, seed, seed.size());
00136                 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00137         }       // check that seed and key don't have same value
00138         while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00139 
00140         Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0);
00141 }
00142 
00143 template <class BLOCK_CIPHER>
00144 byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
00145 {
00146         byte b = m_rng->GenerateByte();
00147 
00148         if (FIPS_140_2_ComplianceEnabled())
00149         {
00150                 m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
00151                 m_lastBlock[m_counter] = b;
00152                 ++m_counter;
00153                 if (m_counter == m_lastBlock.size())
00154                 {
00155                         if (!m_isDifferent)
00156                                 throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
00157                         m_counter = 0;
00158                         m_isDifferent = false;
00159                 }
00160         }
00161 
00162         return b;
00163 }
00164 
00165 NAMESPACE_END
00166 
00167 #endif
00168 
00169 #endif

Generated on Tue Jul 8 23:34:21 2003 for Crypto++ by doxygen 1.3.2