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