Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
4.4 KiB

  1. #ifndef CRYPTOPP_OSRNG_H
  2. #define CRYPTOPP_OSRNG_H
  3. //! \file
  4. #include "config.h"
  5. #ifdef OS_RNG_AVAILABLE
  6. #include "randpool.h"
  7. #include "rng.h"
  8. #include "aes.h"
  9. #include "sha.h"
  10. #include "fips140.h"
  11. NAMESPACE_BEGIN(CryptoPP)
  12. //! Exception class for Operating-System Random Number Generator.
  13. class CRYPTOPP_DLL OS_RNG_Err : public Exception
  14. {
  15. public:
  16. OS_RNG_Err(const std::string &operation);
  17. };
  18. #ifdef NONBLOCKING_RNG_AVAILABLE
  19. #ifdef CRYPTOPP_WIN32_AVAILABLE
  20. class CRYPTOPP_DLL MicrosoftCryptoProvider
  21. {
  22. public:
  23. MicrosoftCryptoProvider();
  24. ~MicrosoftCryptoProvider();
  25. #if defined(_WIN64)
  26. typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h>
  27. #else
  28. typedef unsigned long ProviderHandle;
  29. #endif
  30. ProviderHandle GetProviderHandle() const {return m_hProvider;}
  31. private:
  32. ProviderHandle m_hProvider;
  33. };
  34. #pragma comment(lib, "advapi32.lib")
  35. #endif
  36. //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
  37. class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
  38. {
  39. public:
  40. NonblockingRng();
  41. ~NonblockingRng();
  42. void GenerateBlock(byte *output, size_t size);
  43. protected:
  44. #ifdef CRYPTOPP_WIN32_AVAILABLE
  45. //# ifndef WORKAROUND_MS_BUG_Q258000
  46. // MicrosoftCryptoProvider m_Provider;
  47. //# endif
  48. #else
  49. int m_fd;
  50. #endif
  51. };
  52. #endif
  53. #ifdef BLOCKING_RNG_AVAILABLE
  54. //! encapsulate /dev/random, or /dev/srandom on OpenBSD
  55. class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
  56. {
  57. public:
  58. BlockingRng();
  59. ~BlockingRng();
  60. void GenerateBlock(byte *output, size_t size);
  61. protected:
  62. int m_fd;
  63. };
  64. #endif
  65. CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
  66. //! Automaticly Seeded Randomness Pool
  67. /*! This class seeds itself using an operating system provided RNG. */
  68. class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
  69. {
  70. public:
  71. //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
  72. explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
  73. {Reseed(blocking, seedSize);}
  74. void Reseed(bool blocking = false, unsigned int seedSize = 32);
  75. };
  76. //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
  77. template <class BLOCK_CIPHER>
  78. class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
  79. {
  80. public:
  81. //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
  82. explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
  83. {if (autoSeed) Reseed(blocking);}
  84. void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0);
  85. // exposed for testing
  86. void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
  87. bool CanIncorporateEntropy() const {return true;}
  88. void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
  89. void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
  90. private:
  91. member_ptr<RandomNumberGenerator> m_rng;
  92. };
  93. template <class BLOCK_CIPHER>
  94. void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
  95. {
  96. m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
  97. }
  98. template <class BLOCK_CIPHER>
  99. void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
  100. {
  101. SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
  102. const byte *key;
  103. do
  104. {
  105. OS_GenerateRandomBlock(blocking, seed, seed.size());
  106. if (length > 0)
  107. {
  108. SHA256 hash;
  109. hash.Update(seed, seed.size());
  110. hash.Update(input, length);
  111. hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
  112. }
  113. key = seed + BLOCK_CIPHER::BLOCKSIZE;
  114. } // check that seed and key don't have same value
  115. while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
  116. Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
  117. }
  118. CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
  119. //! this is AutoSeededX917RNG\<AES\> in FIPS mode, otherwise it's AutoSeededRandomPool
  120. #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
  121. typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
  122. #else
  123. typedef AutoSeededRandomPool DefaultAutoSeededRNG;
  124. #endif
  125. NAMESPACE_END
  126. #endif
  127. #endif