Crypto++ 8.2
Free C&
osrng.h
Go to the documentation of this file.
1// osrng.h - originally written and placed in the public domain by Wei Dai
2
3/// \file osrng.h
4/// \brief Classes for access to the operating system's random number generators
5
6#ifndef CRYPTOPP_OSRNG_H
7#define CRYPTOPP_OSRNG_H
8
9#include "config.h"
10
11#if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
12
13#include "cryptlib.h"
14#include "randpool.h"
15#include "smartptr.h"
16#include "fips140.h"
17#include "rng.h"
18#include "aes.h"
19#include "sha.h"
20
21NAMESPACE_BEGIN(CryptoPP)
22
23/// \brief Exception thrown when an operating system error is encountered
24class CRYPTOPP_DLL OS_RNG_Err : public Exception
25{
26public:
27 /// \brief Constructs an OS_RNG_Err
28 /// \param operation the operation or API call when the error occurs
29 OS_RNG_Err(const std::string &operation);
30};
31
32#ifdef NONBLOCKING_RNG_AVAILABLE
33
34#ifdef CRYPTOPP_WIN32_AVAILABLE
35/// \brief Wrapper for Microsoft crypto service provider
36/// \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI
37class CRYPTOPP_DLL MicrosoftCryptoProvider
38{
39public:
40 /// \brief Construct a MicrosoftCryptoProvider
43
44// type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include <windows.h>
45#if defined(USE_MS_CRYPTOAPI)
46# if defined(__CYGWIN__) && defined(__x86_64__)
47 typedef unsigned long long ProviderHandle;
48# elif defined(WIN64) || defined(_WIN64)
49 typedef unsigned __int64 ProviderHandle;
50# else
51 typedef unsigned long ProviderHandle;
52# endif
53#elif defined(USE_MS_CNGAPI)
54 typedef void *PVOID;
55 typedef PVOID ProviderHandle;
56#endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI
57
58 /// \brief Retrieves the provider handle
59 /// \returns CryptoAPI provider handle
60 /// \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext()
61 /// acquires then handle and CryptReleaseContext() releases the handle
62 /// upon destruction. If USE_MS_CNGAPI is in effect, then
63 /// BCryptOpenAlgorithmProvider() acquires then handle and
64 /// BCryptCloseAlgorithmProvider() releases the handle upon destruction.
65 ProviderHandle GetProviderHandle() const {return m_hProvider;}
66
67private:
68 ProviderHandle m_hProvider;
69};
70
71#if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI)
72# pragma comment(lib, "advapi32.lib")
73#endif
74
75#if defined(_MSC_VER) && defined(USE_MS_CNGAPI)
76# pragma comment(lib, "bcrypt.lib")
77#endif
78
79#endif // CRYPTOPP_WIN32_AVAILABLE
80
81/// \brief Wrapper class for /dev/random and /dev/srandom
82/// \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom()
83/// on Windows, or /dev/urandom on Unix and compatibles.
84class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
85{
86public:
87 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; }
88
90
91 /// \brief Construct a NonblockingRng
93
94 /// \brief Generate random array of bytes
95 /// \param output the byte buffer
96 /// \param size the length of the buffer, in bytes
97 /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
98 void GenerateBlock(byte *output, size_t size);
99
100protected:
101#ifdef CRYPTOPP_WIN32_AVAILABLE
102 MicrosoftCryptoProvider m_Provider;
103#else
104 int m_fd;
105#endif
106};
107
108#endif
109
110#if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
111
112/// \brief Wrapper class for /dev/random and /dev/srandom
113/// \details Encapsulates /dev/random on Linux, OS X and Unix; and /dev/srandom on the BSDs.
114/// \note On Linux the /dev/random interface is effectively deprecated. According to the
115/// Kernel Crypto developers, /dev/urandom or getrandom(2) should be used instead. Also
116/// see <A HREF="https://lkml.org/lkml/2017/7/20/993">[RFC PATCH v12 3/4] Linux Random
117/// Number Generator</A> on the kernel-crypto mailing list.
118class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
119{
120public:
121 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
122
123 ~BlockingRng();
124
125 /// \brief Construct a BlockingRng
126 BlockingRng();
127
128 /// \brief Generate random array of bytes
129 /// \param output the byte buffer
130 /// \param size the length of the buffer, in bytes
131 /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
132 void GenerateBlock(byte *output, size_t size);
133
134protected:
135 int m_fd;
136};
137
138#endif
139
140/// OS_GenerateRandomBlock
141/// \brief Generate random array of bytes
142/// \param blocking specifies whther a bobcking or non-blocking generator should be used
143/// \param output the byte buffer
144/// \param size the length of the buffer, in bytes
145/// \details OS_GenerateRandomBlock() uses the underlying operating system's
146/// random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
147/// \details On Unix and compatibles, /dev/urandom is called if blocking is false using
148/// NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
149/// by way of BlockingRng, if available.
150CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
151
152/// \brief Automatically Seeded Randomness Pool
153/// \details This class seeds itself using an operating system provided RNG.
154/// AutoSeededRandomPool was suggested by Leonard Janke.
155class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
156{
157public:
158 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; }
159
161
162 /// \brief Construct an AutoSeededRandomPool
163 /// \param blocking controls seeding with BlockingRng or NonblockingRng
164 /// \param seedSize the size of the seed, in bytes
165 /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
166 /// The parameter is ignored if only one of these is available.
167 explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
168 {Reseed(blocking, seedSize);}
169
170 /// \brief Reseed an AutoSeededRandomPool
171 /// \param blocking controls seeding with BlockingRng or NonblockingRng
172 /// \param seedSize the size of the seed, in bytes
173 void Reseed(bool blocking = false, unsigned int seedSize = 32);
174};
175
176/// \tparam BLOCK_CIPHER a block cipher
177/// \brief Automatically Seeded X9.17 RNG
178/// \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
179/// If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
180/// used, then its a X9.31 conforming generator.
181/// \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER can be any
182/// BlockTransformation derived class.
183/// \sa X917RNG, DefaultAutoSeededRNG
184template <class BLOCK_CIPHER>
186{
187public:
188 static std::string StaticAlgorithmName() { return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")"); }
189
191
192 /// \brief Construct an AutoSeededX917RNG
193 /// \param blocking controls seeding with BlockingRng or NonblockingRng
194 /// \param autoSeed controls auto seeding of the generator
195 /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
196 /// The parameter is ignored if only one of these is available.
197 /// \sa X917RNG
198 explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
199 {if (autoSeed) Reseed(blocking);}
200
201 /// \brief Reseed an AutoSeededX917RNG
202 /// \param blocking controls seeding with BlockingRng or NonblockingRng
203 /// \param additionalEntropy additional entropy to add to the generator
204 /// \param length the size of the additional entropy, in bytes
205 /// \details Internally, the generator uses SHA256 to extract the entropy from
206 /// from the seed and then stretch the material for the block cipher's key
207 /// and initialization vector.
208 void Reseed(bool blocking = false, const byte *additionalEntropy = NULLPTR, size_t length = 0);
209
210 /// \brief Deterministically reseed an AutoSeededX917RNG for testing
211 /// \param key the key to use for the deterministic reseeding
212 /// \param keylength the size of the key, in bytes
213 /// \param seed the seed to use for the deterministic reseeding
214 /// \param timeVector a time vector to use for deterministic reseeding
215 /// \details This is a testing interface for testing purposes, and should \a NOT
216 /// be used in production.
217 void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
218
219 bool CanIncorporateEntropy() const {return true;}
220 void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
221 void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
222 {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
223
224 std::string AlgorithmProvider() const;
225
226private:
228};
229
230template <class BLOCK_CIPHER>
231void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
232{
233 m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
234}
235
236template <class BLOCK_CIPHER>
237void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
238{
239 SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
240 const byte *key;
241 do
242 {
243 OS_GenerateRandomBlock(blocking, seed, seed.size());
244 if (length > 0)
245 {
246 SHA256 hash;
247 hash.Update(seed, seed.size());
248 hash.Update(input, length);
249 hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
250 }
251 key = seed + BLOCK_CIPHER::BLOCKSIZE;
252 } // check that seed and key don't have same value
253 while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
254
255 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULLPTR);
256}
257
258template <class BLOCK_CIPHER>
260{
261 // Hack for now... We need to instantiate one
262 typename BLOCK_CIPHER::Encryption bc;
263 return bc.AlgorithmProvider();
264}
265
266CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
267
268#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
269/// \brief A typedef providing a default generator
270/// \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
271/// If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
272/// AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
274#else
275// AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
276#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
278#else
280#endif
281#endif // CRYPTOPP_DOXYGEN_PROCESSING
282
283NAMESPACE_END
284
285#endif
286
287#endif
Class file for the AES cipher (Rijndael)
Automatically Seeded Randomness Pool.
Definition: osrng.h:156
AutoSeededRandomPool(bool blocking=false, unsigned int seedSize=32)
Construct an AutoSeededRandomPool.
Definition: osrng.h:167
Automatically Seeded X9.17 RNG.
Definition: osrng.h:186
bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: osrng.h:219
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: osrng.h:220
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: osrng.h:259
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: osrng.h:221
AutoSeededX917RNG(bool blocking=false, bool autoSeed=true)
Construct an AutoSeededX917RNG.
Definition: osrng.h:198
void Reseed(bool blocking=false, const byte *additionalEntropy=NULL, size_t length=0)
Reseed an AutoSeededX917RNG.
Definition: osrng.h:237
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:119
Interface for buffered transformations.
Definition: cryptlib.h:1599
A typedef providing a default generator.
Definition: osrng.h:273
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:159
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: iterhash.h:187
ProviderHandle GetProviderHandle() const
Retrieves the provider handle.
Definition: osrng.h:65
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:85
Ensures an object is not copyable.
Definition: misc.h:201
Exception thrown when an operating system error is encountered.
Definition: osrng.h:25
Interface for random number generators.
Definition: cryptlib.h:1384
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: cryptlib.cpp:324
Randomness Pool based on AES-256.
Definition: randpool.h:42
SHA-256 message digest.
Definition: sha.h:65
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:797
SecBlock<byte> typedef.
Definition: secblock.h:1058
ANSI X9.17 RNG.
Definition: rng.h:48
Pointer that overloads operator ->
Definition: smartptr.h:37
Library configuration file.
Abstract base classes that provide a uniform interface to this library.
Classes and functions for the FIPS 140-2 validated library.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:567
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:606
Crypto++ library namespace.
void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size)
OS_GenerateRandomBlock.
Definition: osrng.cpp:236
Class file for Randomness Pool.
Miscellaneous classes for RNGs.
Classes for SHA-1 and SHA-2 family of message digests.
Classes for automatic resource management.