- Main Page
- Namespaces
- Classes
- Files

- File List
- 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 template <class BLOCK_CIPHER>
    00116 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
    00117 {
    00118         m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
    00119
    00120         // for FIPS 140-2
    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 template <class BLOCK_CIPHER>
    00128 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
    00129 {
    00130         SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
    00131         const byte *key;
    00132         do
    00133         {
    00134                 OS_GenerateRandomBlock(blocking, seed, seed.size());
    00135                 key = seed + BLOCK_CIPHER::BLOCKSIZE;
    00136         }       // check that seed and key don't have same value
    00137         while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
    00138
    00139         Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
    00140 }
    00141
    00142 template <class BLOCK_CIPHER>
    00143 byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
    00144 {
    00145         byte b = m_rng->GenerateByte();
    00146
    00147         // for FIPS 140-2
    00148         m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
    00149         m_lastBlock[m_counter] = b;
    00150         ++m_counter;
    00151         if (m_counter == m_lastBlock.size())
    00152         {
    00153                 if (!m_isDifferent)
    00154                         throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
    00155                 m_counter = 0;
    00156                 m_isDifferent = false;
    00157         }
    00158
    00159         return b;
    00160 }
    00161
    00162 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<DES_EDE3>;
    00163
    00164 NAMESPACE_END
    00165
    00166 #endif
    00167
    00168 #endif