File indexing completed on 2025-01-18 09:55:06
0001
0002
0003
0004
0005
0006 #ifndef CRYPTOPP_OSRNG_H
0007 #define CRYPTOPP_OSRNG_H
0008
0009 #include "config.h"
0010
0011 #if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
0012
0013 #include "cryptlib.h"
0014 #include "randpool.h"
0015 #include "smartptr.h"
0016 #include "fips140.h"
0017 #include "hkdf.h"
0018 #include "rng.h"
0019 #include "aes.h"
0020 #include "sha.h"
0021
0022 NAMESPACE_BEGIN(CryptoPP)
0023
0024
0025 class CRYPTOPP_DLL OS_RNG_Err : public Exception
0026 {
0027 public:
0028
0029
0030 OS_RNG_Err(const std::string &operation);
0031 };
0032
0033 #ifdef NONBLOCKING_RNG_AVAILABLE
0034
0035 #ifdef CRYPTOPP_WIN32_AVAILABLE
0036
0037
0038 class CRYPTOPP_DLL MicrosoftCryptoProvider
0039 {
0040 public:
0041
0042 MicrosoftCryptoProvider();
0043 ~MicrosoftCryptoProvider();
0044
0045
0046 #if defined(USE_MS_CRYPTOAPI)
0047 # if defined(__CYGWIN__) && defined(__x86_64__)
0048 typedef unsigned long long ProviderHandle;
0049 # elif defined(WIN64) || defined(_WIN64)
0050 typedef unsigned __int64 ProviderHandle;
0051 # else
0052 typedef unsigned long ProviderHandle;
0053 # endif
0054 #elif defined(USE_MS_CNGAPI)
0055 typedef void *PVOID;
0056 typedef PVOID ProviderHandle;
0057 #endif
0058
0059
0060
0061
0062
0063
0064
0065
0066 ProviderHandle GetProviderHandle() const {return m_hProvider;}
0067
0068 private:
0069 ProviderHandle m_hProvider;
0070 };
0071
0072 #if defined(CRYPTOPP_MSC_VERSION) && defined(USE_MS_CRYPTOAPI)
0073 # pragma comment(lib, "advapi32.lib")
0074 #endif
0075
0076 #if defined(CRYPTOPP_MSC_VERSION) && defined(USE_MS_CNGAPI)
0077 # pragma comment(lib, "bcrypt.lib")
0078 #endif
0079
0080 #endif
0081
0082
0083
0084
0085 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
0086 {
0087 public:
0088 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; }
0089
0090 ~NonblockingRng();
0091
0092
0093 NonblockingRng();
0094
0095
0096
0097
0098
0099 void GenerateBlock(byte *output, size_t size);
0100
0101 protected:
0102 #ifdef CRYPTOPP_WIN32_AVAILABLE
0103 MicrosoftCryptoProvider m_Provider;
0104 #else
0105 int m_fd;
0106 #endif
0107 };
0108
0109 #endif
0110
0111 #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
0112
0113
0114
0115
0116
0117
0118
0119 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
0120 {
0121 public:
0122 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
0123
0124 ~BlockingRng();
0125
0126
0127 BlockingRng();
0128
0129
0130
0131
0132
0133 void GenerateBlock(byte *output, size_t size);
0134
0135 protected:
0136 int m_fd;
0137 };
0138
0139 #endif
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
0152
0153
0154
0155
0156
0157
0158 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
0159 {
0160 public:
0161 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; }
0162
0163 ~AutoSeededRandomPool() {}
0164
0165
0166
0167
0168
0169
0170 explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
0171 {Reseed(blocking, seedSize);}
0172
0173
0174
0175
0176 void Reseed(bool blocking = false, unsigned int seedSize = 32);
0177 };
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 template <class BLOCK_CIPHER>
0190 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
0191 {
0192 public:
0193 static std::string StaticAlgorithmName() {
0194 return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")");
0195 }
0196
0197 ~AutoSeededX917RNG() {}
0198
0199
0200
0201
0202
0203
0204
0205 explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
0206 {if (autoSeed) Reseed(blocking);}
0207
0208
0209
0210
0211
0212
0213
0214
0215 void Reseed(bool blocking = false, const byte *input = NULLPTR, size_t length = 0);
0216
0217
0218
0219
0220
0221
0222
0223
0224 void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
0225
0226 bool CanIncorporateEntropy() const {return true;}
0227 void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
0228 void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
0229 {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
0230
0231 std::string AlgorithmProvider() const;
0232
0233 private:
0234 member_ptr<RandomNumberGenerator> m_rng;
0235 };
0236
0237 template <class BLOCK_CIPHER>
0238 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
0239 {
0240 m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
0241 }
0242
0243 template <class BLOCK_CIPHER>
0244 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
0245 {
0246 enum {BlockSize=BLOCK_CIPHER::BLOCKSIZE};
0247 enum {KeyLength=BLOCK_CIPHER::DEFAULT_KEYLENGTH};
0248 enum {SeedSize=EnumToInt(BlockSize)+EnumToInt(KeyLength)};
0249
0250 SecByteBlock seed(SeedSize), temp(SeedSize);
0251 const byte label[] = "X9.17 key generation";
0252 const byte *key=NULLPTR;
0253
0254 do
0255 {
0256 OS_GenerateRandomBlock(blocking, temp, temp.size());
0257
0258 HKDF<SHA256> hkdf;
0259 hkdf.DeriveKey(
0260 seed, seed.size(),
0261 temp, temp.size(),
0262 input, length,
0263 label, 20
0264 );
0265
0266 key = seed + BlockSize;
0267 }
0268 while (std::memcmp(key, seed, STDMIN((size_t)BlockSize, (size_t)KeyLength)) == 0);
0269
0270 Reseed(key, KeyLength, seed, NULLPTR);
0271 }
0272
0273 template <class BLOCK_CIPHER>
0274 std::string AutoSeededX917RNG<BLOCK_CIPHER>::AlgorithmProvider() const
0275 {
0276
0277 typename BLOCK_CIPHER::Encryption bc;
0278 return bc.AlgorithmProvider();
0279 }
0280
0281 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
0282
0283 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
0284
0285
0286
0287
0288
0289
0290 class DefaultAutoSeededRNG {}
0291 #else
0292
0293 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
0294 typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
0295 #else
0296 typedef AutoSeededRandomPool DefaultAutoSeededRNG;
0297 #endif
0298 #endif
0299
0300 NAMESPACE_END
0301
0302 #endif
0303
0304 #endif