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

Generated on Tue Aug 16 08:38:42 2005 for Crypto++ by  doxygen 1.3.9.1