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