osrng.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. // osrng.h - originally written and placed in the public domain by Wei Dai
  2. /// \file osrng.h
  3. /// \brief Classes for access to the operating system's random number generators
  4. #ifndef CRYPTOPP_OSRNG_H
  5. #define CRYPTOPP_OSRNG_H
  6. #include "config.h"
  7. #if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
  8. #include "cryptlib.h"
  9. #include "randpool.h"
  10. #include "smartptr.h"
  11. #include "fips140.h"
  12. #include "hkdf.h"
  13. #include "rng.h"
  14. #include "aes.h"
  15. #include "sha.h"
  16. NAMESPACE_BEGIN(CryptoPP)
  17. /// \brief Exception thrown when an operating system error is encountered
  18. class CRYPTOPP_DLL OS_RNG_Err : public Exception
  19. {
  20. public:
  21. /// \brief Constructs an OS_RNG_Err
  22. /// \param operation the operation or API call when the error occurs
  23. OS_RNG_Err(const std::string &operation);
  24. };
  25. #ifdef NONBLOCKING_RNG_AVAILABLE
  26. #ifdef CRYPTOPP_WIN32_AVAILABLE
  27. /// \brief Wrapper for Microsoft crypto service provider
  28. /// \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI
  29. class CRYPTOPP_DLL MicrosoftCryptoProvider
  30. {
  31. public:
  32. /// \brief Construct a MicrosoftCryptoProvider
  33. MicrosoftCryptoProvider();
  34. ~MicrosoftCryptoProvider();
  35. // type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include <windows.h>
  36. #if defined(USE_MS_CRYPTOAPI)
  37. # if defined(__CYGWIN__) && defined(__x86_64__)
  38. typedef unsigned long long ProviderHandle;
  39. # elif defined(WIN64) || defined(_WIN64)
  40. typedef unsigned __int64 ProviderHandle;
  41. # else
  42. typedef unsigned long ProviderHandle;
  43. # endif
  44. #elif defined(USE_MS_CNGAPI)
  45. typedef void *PVOID;
  46. typedef PVOID ProviderHandle;
  47. #endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI
  48. /// \brief Retrieves the provider handle
  49. /// \return CryptoAPI provider handle
  50. /// \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext()
  51. /// acquires then handle and CryptReleaseContext() releases the handle
  52. /// upon destruction. If USE_MS_CNGAPI is in effect, then
  53. /// BCryptOpenAlgorithmProvider() acquires then handle and
  54. /// BCryptCloseAlgorithmProvider() releases the handle upon destruction.
  55. ProviderHandle GetProviderHandle() const {return m_hProvider;}
  56. private:
  57. ProviderHandle m_hProvider;
  58. };
  59. #if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI)
  60. # pragma comment(lib, "advapi32.lib")
  61. #endif
  62. #if defined(_MSC_VER) && defined(USE_MS_CNGAPI)
  63. # pragma comment(lib, "bcrypt.lib")
  64. #endif
  65. #endif // CRYPTOPP_WIN32_AVAILABLE
  66. /// \brief Wrapper class for /dev/random and /dev/srandom
  67. /// \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom()
  68. /// on Windows, or /dev/urandom on Unix and compatibles.
  69. class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
  70. {
  71. public:
  72. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; }
  73. ~NonblockingRng();
  74. /// \brief Construct a NonblockingRng
  75. NonblockingRng();
  76. /// \brief Generate random array of bytes
  77. /// \param output the byte buffer
  78. /// \param size the length of the buffer, in bytes
  79. /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
  80. void GenerateBlock(byte *output, size_t size);
  81. protected:
  82. #ifdef CRYPTOPP_WIN32_AVAILABLE
  83. MicrosoftCryptoProvider m_Provider;
  84. #else
  85. int m_fd;
  86. #endif
  87. };
  88. #endif
  89. #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
  90. /// \brief Wrapper class for /dev/random and /dev/srandom
  91. /// \details Encapsulates /dev/random on Linux, OS X and Unix; and /dev/srandom on the BSDs.
  92. /// \note On Linux the /dev/random interface is effectively deprecated. According to the
  93. /// Kernel Crypto developers, /dev/urandom or getrandom(2) should be used instead. Also
  94. /// see <A HREF="https://lkml.org/lkml/2017/7/20/993">[RFC PATCH v12 3/4] Linux Random
  95. /// Number Generator</A> on the kernel-crypto mailing list.
  96. class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
  97. {
  98. public:
  99. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
  100. ~BlockingRng();
  101. /// \brief Construct a BlockingRng
  102. BlockingRng();
  103. /// \brief Generate random array of bytes
  104. /// \param output the byte buffer
  105. /// \param size the length of the buffer, in bytes
  106. /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
  107. void GenerateBlock(byte *output, size_t size);
  108. protected:
  109. int m_fd;
  110. };
  111. #endif
  112. /// OS_GenerateRandomBlock
  113. /// \brief Generate random array of bytes
  114. /// \param blocking specifies whether a blocking or non-blocking generator should be used
  115. /// \param output the byte buffer
  116. /// \param size the length of the buffer, in bytes
  117. /// \details OS_GenerateRandomBlock() uses the underlying operating system's
  118. /// random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
  119. /// \details On Unix and compatibles, /dev/urandom is called if blocking is false using
  120. /// NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
  121. /// by way of BlockingRng, if available.
  122. CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
  123. /// \brief Automatically Seeded Randomness Pool
  124. /// \details This class seeds itself using an operating system provided RNG.
  125. /// AutoSeededRandomPool was suggested by Leonard Janke.
  126. /// \details You should reseed the generator after a fork() to avoid multiple generators
  127. /// with the same internal state.
  128. class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
  129. {
  130. public:
  131. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; }
  132. ~AutoSeededRandomPool() {}
  133. /// \brief Construct an AutoSeededRandomPool
  134. /// \param blocking controls seeding with BlockingRng or NonblockingRng
  135. /// \param seedSize the size of the seed, in bytes
  136. /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
  137. /// The parameter is ignored if only one of these is available.
  138. explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
  139. {Reseed(blocking, seedSize);}
  140. /// \brief Reseed an AutoSeededRandomPool
  141. /// \param blocking controls seeding with BlockingRng or NonblockingRng
  142. /// \param seedSize the size of the seed, in bytes
  143. void Reseed(bool blocking = false, unsigned int seedSize = 32);
  144. };
  145. /// \tparam BLOCK_CIPHER a block cipher
  146. /// \brief Automatically Seeded X9.17 RNG
  147. /// \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
  148. /// If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
  149. /// used, then its a X9.31 conforming generator.
  150. /// \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER
  151. /// can be any BlockTransformation derived class.
  152. /// \details You should reseed the generator after a fork() to avoid multiple generators
  153. /// with the same internal state.
  154. /// \sa X917RNG, DefaultAutoSeededRNG
  155. template <class BLOCK_CIPHER>
  156. class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
  157. {
  158. public:
  159. static std::string StaticAlgorithmName() {
  160. return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")");
  161. }
  162. ~AutoSeededX917RNG() {}
  163. /// \brief Construct an AutoSeededX917RNG
  164. /// \param blocking controls seeding with BlockingRng or NonblockingRng
  165. /// \param autoSeed controls auto seeding of the generator
  166. /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
  167. /// The parameter is ignored if only one of these is available.
  168. /// \sa X917RNG
  169. explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
  170. {if (autoSeed) Reseed(blocking);}
  171. /// \brief Reseed an AutoSeededX917RNG
  172. /// \param blocking controls seeding with BlockingRng or NonblockingRng
  173. /// \param input additional entropy to add to the generator
  174. /// \param length the size of the additional entropy, in bytes
  175. /// \details Internally, the generator uses SHA256 to extract the entropy from
  176. /// from the seed and then stretch the material for the block cipher's key
  177. /// and initialization vector.
  178. void Reseed(bool blocking = false, const byte *input = NULLPTR, size_t length = 0);
  179. /// \brief Deterministically reseed an AutoSeededX917RNG for testing
  180. /// \param key the key to use for the deterministic reseeding
  181. /// \param keylength the size of the key, in bytes
  182. /// \param seed the seed to use for the deterministic reseeding
  183. /// \param timeVector a time vector to use for deterministic reseeding
  184. /// \details This is a testing interface for testing purposes, and should \a NOT
  185. /// be used in production.
  186. void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
  187. bool CanIncorporateEntropy() const {return true;}
  188. void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
  189. void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
  190. {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
  191. std::string AlgorithmProvider() const;
  192. private:
  193. member_ptr<RandomNumberGenerator> m_rng;
  194. };
  195. template <class BLOCK_CIPHER>
  196. void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
  197. {
  198. m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
  199. }
  200. template <class BLOCK_CIPHER>
  201. void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
  202. {
  203. enum {BlockSize=BLOCK_CIPHER::BLOCKSIZE};
  204. enum {KeyLength=BLOCK_CIPHER::DEFAULT_KEYLENGTH};
  205. enum {SeedSize=EnumToInt(BlockSize)+EnumToInt(KeyLength)};
  206. SecByteBlock seed(SeedSize), temp(SeedSize);
  207. const byte label[] = "X9.17 key generation";
  208. const byte *key=NULLPTR;
  209. do
  210. {
  211. OS_GenerateRandomBlock(blocking, temp, temp.size());
  212. HKDF<SHA256> hkdf;
  213. hkdf.DeriveKey(
  214. seed, seed.size(), // derived secret
  215. temp, temp.size(), // instance secret
  216. input, length, // user secret
  217. label, 20 // unique label
  218. );
  219. key = seed + BlockSize;
  220. } // check that seed and key don't have same value
  221. while (memcmp(key, seed, STDMIN((size_t)BlockSize, (size_t)KeyLength)) == 0);
  222. Reseed(key, KeyLength, seed, NULLPTR);
  223. }
  224. template <class BLOCK_CIPHER>
  225. std::string AutoSeededX917RNG<BLOCK_CIPHER>::AlgorithmProvider() const
  226. {
  227. // Hack for now... We need to instantiate one
  228. typename BLOCK_CIPHER::Encryption bc;
  229. return bc.AlgorithmProvider();
  230. }
  231. CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
  232. #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
  233. /// \brief A typedef providing a default generator
  234. /// \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
  235. /// If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
  236. /// AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
  237. /// \details You should reseed the generator after a fork() to avoid multiple generators
  238. /// with the same internal state.
  239. class DefaultAutoSeededRNG {}
  240. #else
  241. // AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
  242. #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
  243. typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
  244. #else
  245. typedef AutoSeededRandomPool DefaultAutoSeededRNG;
  246. #endif
  247. #endif // CRYPTOPP_DOXYGEN_PROCESSING
  248. NAMESPACE_END
  249. #endif
  250. #endif