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

Generated on Sat Dec 23 02:07:09 2006 for Crypto++ by  doxygen 1.5.1-p1