Crypto++ 8.9
Free C++ class library of cryptographic schemes
drbg.h
Go to the documentation of this file.
1// drbg.h - written and placed in public domain by Jeffrey Walton.
2
3/// \file drbg.h
4/// \brief Classes for NIST DRBGs from SP 800-90A
5/// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
6/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
7/// \since Crypto++ 6.0
8
9#ifndef CRYPTOPP_NIST_DRBG_H
10#define CRYPTOPP_NIST_DRBG_H
11
12#include "cryptlib.h"
13#include "secblock.h"
14#include "hmac.h"
15#include "sha.h"
16
17NAMESPACE_BEGIN(CryptoPP)
18
19/// \brief Interface for NIST DRBGs from SP 800-90A
20/// \details NIST_DRBG is the base class interface for NIST DRBGs from SP 800-90A Rev 1 (June 2015)
21/// \details You should reseed the generator after a fork() to avoid multiple generators
22/// with the same internal state.
23/// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
24/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
25/// \since Crypto++ 6.0
27{
28public:
29 /// \brief Exception thrown when a NIST DRBG encounters an error
30 class Err : public Exception
31 {
32 public:
33 explicit Err(const std::string &c, const std::string &m)
34 : Exception(OTHER_ERROR, c + ": " + m) {}
35 };
36
37public:
38 virtual ~NIST_DRBG() {}
39
40 /// \brief Determines if a generator can accept additional entropy
41 /// \return true
42 /// \details All NIST_DRBG return true
43 virtual bool CanIncorporateEntropy() const {return true;}
44
45 /// \brief Update RNG state with additional unpredictable values
46 /// \param input the entropy to add to the generator
47 /// \param length the size of the input buffer
48 /// \throw NIST_DRBG::Err if the generator is reseeded with insufficient entropy
49 /// \details NIST instantiation and reseed requirements demand the generator is constructed
50 /// with at least <tt>MINIMUM_ENTROPY</tt> entropy. The byte array for <tt>input</tt> must
51 /// meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
52 /// SP 800-90C</A> requirements.
53 virtual void IncorporateEntropy(const byte *input, size_t length)=0;
54
55 /// \brief Update RNG state with additional unpredictable values
56 /// \param entropy the entropy to add to the generator
57 /// \param entropyLength the size of the input buffer
58 /// \param additional additional input to add to the generator
59 /// \param additionaLength the size of the additional input buffer
60 /// \throw NIST_DRBG::Err if the generator is reseeded with insufficient entropy
61 /// \details IncorporateEntropy() is an overload provided to match NIST requirements. NIST
62 /// instantiation and reseed requirements demand the generator is constructed with at least
63 /// <tt>MINIMUM_ENTROPY</tt> entropy. The byte array for <tt>entropy</tt> must meet
64 /// <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
65 ///! SP 800-90C</A> requirements.
66 virtual void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
67
68 /// \brief Generate random array of bytes
69 /// \param output the byte buffer
70 /// \param size the length of the buffer, in bytes
71 /// \throw NIST_DRBG::Err if a reseed is required
72 /// \throw NIST_DRBG::Err if the size exceeds <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
73 virtual void GenerateBlock(byte *output, size_t size)=0;
74
75 /// \brief Generate random array of bytes
76 /// \param additional additional input to add to the generator
77 /// \param additionaLength the size of the additional input buffer
78 /// \param output the byte buffer
79 /// \param size the length of the buffer, in bytes
80 /// \throw NIST_DRBG::Err if a reseed is required
81 /// \throw NIST_DRBG::Err if the size exceeds <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
82 /// \details GenerateBlock() is an overload provided to match NIST requirements. The byte
83 /// array for <tt>additional</tt> input is optional. If present the additional randomness
84 /// is mixed before generating the output bytes.
85 virtual void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)=0;
86
87 /// \brief Provides the security strength
88 /// \return The security strength of the generator, in bytes
89 /// \details The equivalent class constant is <tt>SECURITY_STRENGTH</tt>
90 virtual unsigned int SecurityStrength() const=0;
91
92 /// \brief Provides the seed length
93 /// \return The seed size of the generator, in bytes
94 /// \details The equivalent class constant is <tt>SEED_LENGTH</tt>. The size is
95 /// used to maintain internal state of <tt>V</tt> and <tt>C</tt>.
96 virtual unsigned int SeedLength() const=0;
97
98 /// \brief Provides the minimum entropy size
99 /// \return The minimum entropy size required by the generator, in bytes
100 /// \details The equivalent class constant is <tt>MINIMUM_ENTROPY</tt>. All NIST DRBGs must
101 /// be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy. The bytes must
102 /// meet <A HREF="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
103 /// SP 800-90C</A> requirements.
104 virtual unsigned int MinEntropyLength() const=0;
105
106 /// \brief Provides the maximum entropy size
107 /// \return The maximum entropy size that can be consumed by the generator, in bytes
108 /// \details The equivalent class constant is <tt>MAXIMUM_ENTROPY</tt>. The bytes must
109 /// meet <A HREF="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
110 /// SP 800-90C</A> requirements. <tt>MAXIMUM_ENTROPY</tt> has been reduced from
111 /// 2<sup>35</sup> to <tt>INT_MAX</tt> to fit the underlying C++ datatype.
112 virtual unsigned int MaxEntropyLength() const=0;
113
114 /// \brief Provides the minimum nonce size
115 /// \return The minimum nonce size recommended for the generator, in bytes
116 /// \details The equivalent class constant is <tt>MINIMUM_NONCE</tt>. If a nonce is not
117 /// required then <tt>MINIMUM_NONCE</tt> is 0. <tt>Hash_DRBG</tt> does not require a
118 /// nonce, while <tt>HMAC_DRBG</tt> and <tt>CTR_DRBG</tt> require a nonce.
119 virtual unsigned int MinNonceLength() const=0;
120
121 /// \brief Provides the maximum nonce size
122 /// \return The maximum nonce that can be consumed by the generator, in bytes
123 /// \details The equivalent class constant is <tt>MAXIMUM_NONCE</tt>. <tt>MAXIMUM_NONCE</tt>
124 /// has been reduced from 2<sup>35</sup> to <tt>INT_MAX</tt> to fit the underlying C++ datatype.
125 /// If a nonce is not required then <tt>MINIMUM_NONCE</tt> is 0. <tt>Hash_DRBG</tt> does not
126 /// require a nonce, while <tt>HMAC_DRBG</tt> and <tt>CTR_DRBG</tt> require a nonce.
127 virtual unsigned int MaxNonceLength() const=0;
128
129 /// \brief Provides the maximum size of a request to GenerateBlock
130 /// \return The maximum size of a request to GenerateBlock(), in bytes
131 /// \details The equivalent class constant is <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
132 virtual unsigned int MaxBytesPerRequest() const=0;
133
134 /// \brief Provides the maximum number of requests before a reseed
135 /// \return The maximum number of requests before a reseed, in bytes
136 /// \details The equivalent class constant is <tt>MAXIMUM_REQUESTS_BEFORE_RESEED</tt>.
137 /// <tt>MAXIMUM_REQUESTS_BEFORE_RESEED</tt> has been reduced from 2<sup>48</sup> to <tt>INT_MAX</tt>
138 /// to fit the underlying C++ datatype.
139 virtual unsigned int MaxRequestBeforeReseed() const=0;
140
141protected:
142 virtual void DRBG_Instantiate(const byte* entropy, size_t entropyLength,
143 const byte* nonce, size_t nonceLength, const byte* personalization, size_t personalizationLength)=0;
144
145 virtual void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
146};
147
148// *************************************************************
149
150/// \tparam HASH NIST approved hash derived from HashTransformation
151/// \tparam STRENGTH security strength, in bytes
152/// \tparam SEEDLENGTH seed length, in bytes
153/// \brief Hash_DRBG from SP 800-90A Rev 1 (June 2015)
154/// \details The NIST Hash DRBG is instantiated with a number of parameters. Two of the parameters,
155/// Security Strength and Seed Length, depend on the hash and are specified as template parameters.
156/// The remaining parameters are included in the class. The parameters and their values are listed
157/// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38).
158/// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto
159/// 2<sup>48</sup> requests before a reseed. However, Hash_DRBG limits it to <tt>INT_MAX</tt> due
160/// to the limited data range of an int.
161/// \details You should reseed the generator after a fork() to avoid multiple generators
162/// with the same internal state.
163/// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
164/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
165/// \since Crypto++ 6.0
166template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
167class Hash_DRBG : public NIST_DRBG, public NotCopyable
168{
169public:
170 CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH);
171 CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH);
172 CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH);
173 CRYPTOPP_CONSTANT(MINIMUM_NONCE=0);
174 CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0);
175 CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0);
176 CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX);
177 CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX);
178 CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX);
179 CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX);
180 CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536);
181 CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX);
182
183 static std::string StaticAlgorithmName() { return std::string("Hash_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); }
184
185 /// \brief Construct a Hash DRBG
186 /// \param entropy the entropy to instantiate the generator
187 /// \param entropyLength the size of the entropy buffer
188 /// \param nonce additional input to instantiate the generator
189 /// \param nonceLength the size of the nonce buffer
190 /// \param personalization additional input to instantiate the generator
191 /// \param personalizationLength the size of the personalization buffer
192 /// \throw NIST_DRBG::Err if the generator is instantiated with insufficient entropy
193 /// \details All NIST DRBGs must be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy.
194 /// The byte array for <tt>entropy</tt> must meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST
195 /// SP 800-90B or SP 800-90C</A> requirements.
196 /// \details The <tt>nonce</tt> and <tt>personalization</tt> are optional byte arrays. If <tt>nonce</tt> is supplied,
197 /// then it should be at least <tt>MINIMUM_NONCE</tt> bytes of entropy.
198 /// \details An example of instantiating a SHA256 generator is shown below.
199 /// The example provides more entropy than required for SHA256. The <tt>NonblockingRng</tt> meets the
200 /// requirements of <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or SP 800-90C</A>.
201 /// RDRAND() and RDSEED() generators would work as well.
202 /// <pre>
203 /// SecByteBlock entropy(48), result(128);
204 /// NonblockingRng prng;
205 /// RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
206 ///
207 /// Hash_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16);
208 /// drbg.GenerateBlock(result, result.size());
209 /// </pre>
210 Hash_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR,
211 size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
212 : NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0)
213 {
214 if (m_c.data()) // GCC analyzer warning
215 std::memset(m_c.data(), 0x00, m_c.size());
216 if (m_v.data()) // GCC analyzer warning
217 std::memset(m_v.data(), 0x00, m_v.size());
218
219 if (entropy != NULLPTR && entropyLength != 0)
220 DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
221 }
222
223 unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
224 unsigned int SeedLength() const {return SEED_LENGTH;}
225 unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
226 unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
227 unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
228 unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
229 unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
230 unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
231
232 void IncorporateEntropy(const byte *input, size_t length)
233 {return DRBG_Reseed(input, length, NULLPTR, 0);}
234
235 void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
236 {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
237
238 void GenerateBlock(byte *output, size_t size)
239 {return Hash_Generate(NULLPTR, 0, output, size);}
240
241 void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
242 {return Hash_Generate(additional, additionaLength, output, size);}
243
244 std::string AlgorithmProvider() const
245 {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
246
247protected:
248 // 10.1.1.2 Instantiation of Hash_DRBG (p.39)
249 void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
250 const byte* personalization, size_t personalizationLength);
251
252 // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
253 void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
254
255 // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
256 void Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
257
258 // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
259 void Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
260 const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen);
261
262private:
263 HASH m_hash;
264 SecByteBlock m_c, m_v, m_temp;
265 word64 m_reseed;
266};
267
268// typedef Hash_DRBG<SHA1, 128/8, 440/8> Hash_SHA1_DRBG;
269// typedef Hash_DRBG<SHA256, 128/8, 440/8> Hash_SHA256_DRBG;
270// typedef Hash_DRBG<SHA384, 256/8, 888/8> Hash_SHA384_DRBG;
271// typedef Hash_DRBG<SHA512, 256/8, 888/8> Hash_SHA512_DRBG;
272
273// *************************************************************
274
275/// \tparam HASH NIST approved hash derived from HashTransformation
276/// \tparam STRENGTH security strength, in bytes
277/// \tparam SEEDLENGTH seed length, in bytes
278/// \brief HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
279/// \details The NIST HMAC DRBG is instantiated with a number of parameters. Two of the parameters,
280/// Security Strength and Seed Length, depend on the hash and are specified as template parameters.
281/// The remaining parameters are included in the class. The parameters and their values are listed
282/// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38).
283/// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto 2<sup>48</sup> requests
284/// before a reseed. However, HMAC_DRBG limits it to <tt>INT_MAX</tt> due to the limited data range of an int.
285/// \details You should reseed the generator after a fork() to avoid multiple generators
286/// with the same internal state.
287/// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
288/// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
289/// \since Crypto++ 6.0
290template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
291class HMAC_DRBG : public NIST_DRBG, public NotCopyable
292{
293public:
294 CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH);
295 CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH);
296 CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH);
297 CRYPTOPP_CONSTANT(MINIMUM_NONCE=0);
298 CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0);
299 CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0);
300 CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX);
301 CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX);
302 CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX);
303 CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX);
304 CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536);
305 CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX);
306
307 static std::string StaticAlgorithmName() { return std::string("HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); }
308
309 /// \brief Construct a HMAC DRBG
310 /// \param entropy the entropy to instantiate the generator
311 /// \param entropyLength the size of the entropy buffer
312 /// \param nonce additional input to instantiate the generator
313 /// \param nonceLength the size of the nonce buffer
314 /// \param personalization additional input to instantiate the generator
315 /// \param personalizationLength the size of the personalization buffer
316 /// \throw NIST_DRBG::Err if the generator is instantiated with insufficient entropy
317 /// \details All NIST DRBGs must be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy.
318 /// The byte array for <tt>entropy</tt> must meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST
319 /// SP 800-90B or SP 800-90C</A> requirements.
320 /// \details The <tt>nonce</tt> and <tt>personalization</tt> are optional byte arrays. If <tt>nonce</tt> is supplied,
321 /// then it should be at least <tt>MINIMUM_NONCE</tt> bytes of entropy.
322 /// \details An example of instantiating a SHA256 generator is shown below.
323 /// The example provides more entropy than required for SHA256. The <tt>NonblockingRng</tt> meets the
324 /// requirements of <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or SP 800-90C</A>.
325 /// RDRAND() and RDSEED() generators would work as well.
326 /// <pre>
327 /// SecByteBlock entropy(48), result(128);
328 /// NonblockingRng prng;
329 /// RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
330 ///
331 /// HMAC_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16);
332 /// drbg.GenerateBlock(result, result.size());
333 /// </pre>
334 HMAC_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR,
335 size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
336 : NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
337 {
338 if (m_k.data()) // GCC analyzer warning
339 std::memset(m_k, 0x00, m_k.size());
340 if (m_v.data()) // GCC analyzer warning
341 std::memset(m_v, 0x00, m_v.size());
342
343 if (entropy != NULLPTR && entropyLength != 0)
344 DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
345 }
346
347 unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
348 unsigned int SeedLength() const {return SEED_LENGTH;}
349 unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
350 unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
351 unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
352 unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
353 unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
354 unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
355
356 void IncorporateEntropy(const byte *input, size_t length)
357 {return DRBG_Reseed(input, length, NULLPTR, 0);}
358
359 void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
360 {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
361
362 void GenerateBlock(byte *output, size_t size)
363 {return HMAC_Generate(NULLPTR, 0, output, size);}
364
365 void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
366 {return HMAC_Generate(additional, additionaLength, output, size);}
367
368 std::string AlgorithmProvider() const
369 {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
370
371protected:
372 // 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
373 void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
374 const byte* personalization, size_t personalizationLength);
375
376 // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
377 void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
378
379 // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
380 void HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
381
382 // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
383 void HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3);
384
385private:
386 HMAC<HASH> m_hmac;
387 SecByteBlock m_k, m_v;
388 word64 m_reseed;
389};
390
391// typedef HMAC_DRBG<SHA1, 128/8, 440/8> HMAC_SHA1_DRBG;
392// typedef HMAC_DRBG<SHA256, 128/8, 440/8> HMAC_SHA256_DRBG;
393// typedef HMAC_DRBG<SHA384, 256/8, 888/8> HMAC_SHA384_DRBG;
394// typedef HMAC_DRBG<SHA512, 256/8, 888/8> HMAC_SHA512_DRBG;
395
396// *************************************************************
397
398// 10.1.1.2 Instantiation of Hash_DRBG (p.39)
399template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
400void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
401 const byte* personalization, size_t personalizationLength)
402{
403 // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
404 // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
405 // personalization string during instantiation, or in the additional input during reseeding and generation,
406 // but this is not required and does not increase the "official" security strength of the DRBG
407 // instantiation that is recorded in the internal state.
408 CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
409 if (entropyLength < MINIMUM_ENTROPY)
410 throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during instantiate");
411
412 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
413 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
414 CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
415 CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
416 CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
417
418 const byte zero = 0;
419 SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
420 Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size());
421 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
422
423 m_v.swap(t1); m_c.swap(t2);
424 m_reseed = 1;
425}
426
427// 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
428template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
429void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
430{
431 // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
432 // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
433 // personalization string during instantiation, or in the additional input during reseeding and generation,
434 // but this is not required and does not increase the "official" security strength of the DRBG
435 // instantiation that is recorded in the internal state..
436 CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
437 if (entropyLength < MINIMUM_ENTROPY)
438 throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during reseed");
439
440 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
441 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
442 CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
443 CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
444
445 const byte zero = 0, one = 1;
446 SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
447 Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
448 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
449
450 m_v.swap(t1); m_c.swap(t2);
451 m_reseed = 1;
452}
453
454// 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
455template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
456void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
457{
458 // Step 1
459 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
460 throw NIST_DRBG::Err("Hash_DRBG", "Reseed required");
461
462 if (size > MaxBytesPerRequest())
463 throw NIST_DRBG::Err("Hash_DRBG", "Request size exceeds limit");
464
465 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
466 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
467 CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
468
469 // Step 2
470 if (additional && additionaLength)
471 {
472 const byte two = 2;
473 m_temp.New(HASH::DIGESTSIZE);
474
475 m_hash.Update(&two, 1);
476 m_hash.Update(m_v, m_v.size());
477 m_hash.Update(additional, additionaLength);
478 m_hash.Final(m_temp);
479
480 CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
481 int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
482 while (j>=0)
483 {
484 carry = m_v[i] + m_temp[j] + carry;
485 m_v[i] = static_cast<byte>(carry);
486 i--; j--; carry >>= 8;
487 }
488 while (i>=0)
489 {
490 carry = m_v[i] + carry;
491 m_v[i] = static_cast<byte>(carry);
492 i--; carry >>= 8;
493 }
494 }
495
496 // Step 3
497 {
498 m_temp.Assign(m_v);
499 while (size)
500 {
501 m_hash.Update(m_temp, m_temp.size());
502 size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
503 m_hash.TruncatedFinal(output, count);
504
505 IncrementCounterByOne(m_temp, static_cast<unsigned int>(m_temp.size()));
506 size -= count; output += count;
507 }
508 }
509
510 // Steps 4-7
511 {
512 const byte three = 3;
513 m_temp.New(HASH::DIGESTSIZE);
514
515 m_hash.Update(&three, 1);
516 m_hash.Update(m_v, m_v.size());
517 m_hash.Final(m_temp);
518
519 CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
520 CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
521 int carry=0, k=sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
522
523 while (k>=0)
524 {
525 carry = m_v[i] + m_c[i] + m_temp[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
526 m_v[i] = static_cast<byte>(carry);
527 i--; j--; k--; carry >>= 8;
528 }
529
530 while (j>=0)
531 {
532 carry = m_v[i] + m_c[i] + m_temp[j] + carry;
533 m_v[i] = static_cast<byte>(carry);
534 i--; j--; carry >>= 8;
535 }
536
537 while (i>=0)
538 {
539 carry = m_v[i] + m_c[i] + carry;
540 m_v[i] = static_cast<byte>(carry);
541 i--; carry >>= 8;
542 }
543 }
544
545 m_reseed++;
546}
547
548// 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
549template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
550void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
551 const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen)
552{
553 byte counter = 1;
554 word32 bits = ConditionalByteReverse(BIG_ENDIAN_ORDER, static_cast<word32>(outlen*8));
555
556 while (outlen)
557 {
558 m_hash.Update(&counter, 1);
559 m_hash.Update(reinterpret_cast<const byte*>(&bits), 4);
560
561 if (input1 && inlen1)
562 m_hash.Update(input1, inlen1);
563 if (input2 && inlen2)
564 m_hash.Update(input2, inlen2);
565 if (input3 && inlen3)
566 m_hash.Update(input3, inlen3);
567 if (input4 && inlen4)
568 m_hash.Update(input4, inlen4);
569
570 size_t count = STDMIN(outlen, (size_t)HASH::DIGESTSIZE);
571 m_hash.TruncatedFinal(output, count);
572
573 output += count; outlen -= count;
574 counter++;
575 }
576}
577
578// *************************************************************
579
580// 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
581template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
582void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
583 const byte* personalization, size_t personalizationLength)
584{
585 // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
586 // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
587 // personalization string during instantiation, or in the additional input during reseeding and generation,
588 // but this is not required and does not increase the "official" security strength of the DRBG
589 // instantiation that is recorded in the internal state.
590 CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
591 if (entropyLength < MINIMUM_ENTROPY)
592 throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during instantiate");
593
594 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
595 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
596 CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
597 CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
598 CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
599
600 std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0));
601 std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1));
602
603 HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
604 m_reseed = 1;
605}
606
607// 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
608template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
609void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
610{
611 // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
612 // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
613 // personalization string during instantiation, or in the additional input during reseeding and generation,
614 // but this is not required and does not increase the "official" security strength of the DRBG
615 // instantiation that is recorded in the internal state..
616 CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
617 if (entropyLength < MINIMUM_ENTROPY)
618 throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during reseed");
619
620 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
621 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
622 CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
623 CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
624
625 HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
626 m_reseed = 1;
627}
628
629// 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
630template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
631void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
632{
633 // Step 1
634 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
635 throw NIST_DRBG::Err("HMAC_DRBG", "Reseed required");
636
637 if (size > MaxBytesPerRequest())
638 throw NIST_DRBG::Err("HMAC_DRBG", "Request size exceeds limit");
639
640 // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
641 // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
642 CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
643
644 // Step 2
645 if (additional && additionaLength)
646 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
647
648 // Step 3
649 m_hmac.SetKey(m_k, m_k.size());
650
651 while (size)
652 {
653 m_hmac.Update(m_v, m_v.size());
654 m_hmac.TruncatedFinal(m_v, m_v.size());
655
656 size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
657 std::memcpy(output, m_v, count);
658 size -= count; output += count;
659 }
660
661 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
662 m_reseed++;
663}
664
665// 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
666template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
667void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3)
668{
669 const byte zero = 0, one = 1;
670
671 // Step 1
672 m_hmac.SetKey(m_k, m_k.size());
673 m_hmac.Update(m_v, m_v.size());
674 m_hmac.Update(&zero, 1);
675
676 if (input1 && inlen1)
677 m_hmac.Update(input1, inlen1);
678 if (input2 && inlen2)
679 m_hmac.Update(input2, inlen2);
680 if (input3 && inlen3)
681 m_hmac.Update(input3, inlen3);
682
683 m_hmac.TruncatedFinal(m_k, m_k.size());
684
685 // Step 2
686 m_hmac.SetKey(m_k, m_k.size());
687 m_hmac.Update(m_v, m_v.size());
688
689 m_hmac.TruncatedFinal(m_v, m_v.size());
690
691 // Step 3
692 if ((inlen1 | inlen2 | inlen3) == 0)
693 return;
694
695 // Step 4
696 m_hmac.SetKey(m_k, m_k.size());
697 m_hmac.Update(m_v, m_v.size());
698 m_hmac.Update(&one, 1);
699
700 if (input1 && inlen1)
701 m_hmac.Update(input1, inlen1);
702 if (input2 && inlen2)
703 m_hmac.Update(input2, inlen2);
704 if (input3 && inlen3)
705 m_hmac.Update(input3, inlen3);
706
707 m_hmac.TruncatedFinal(m_k, m_k.size());
708
709 // Step 5
710 m_hmac.SetKey(m_k, m_k.size());
711 m_hmac.Update(m_v, m_v.size());
712
713 m_hmac.TruncatedFinal(m_v, m_v.size());
714}
715
716NAMESPACE_END
717
718#endif // CRYPTOPP_NIST_DRBG_H
Base class for all exceptions thrown by the library.
Definition cryptlib.h:164
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
Definition drbg.h:292
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition drbg.h:356
unsigned int SeedLength() const
Provides the seed length.
Definition drbg.h:348
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition drbg.h:354
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition drbg.h:349
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition drbg.h:359
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition drbg.h:362
unsigned int SecurityStrength() const
Provides the security strength.
Definition drbg.h:347
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition drbg.h:353
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition drbg.h:351
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition drbg.h:350
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition drbg.h:368
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition drbg.h:365
HMAC_DRBG(const byte *entropy=NULL, size_t entropyLength=STRENGTH, const byte *nonce=NULL, size_t nonceLength=0, const byte *personalization=NULL, size_t personalizationLength=0)
Construct a HMAC DRBG.
Definition drbg.h:334
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition drbg.h:352
HMAC.
Definition hmac.h:53
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
Definition drbg.h:168
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition drbg.h:227
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition drbg.h:226
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition drbg.h:232
unsigned int SeedLength() const
Provides the seed length.
Definition drbg.h:224
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition drbg.h:241
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition drbg.h:230
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition drbg.h:229
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition drbg.h:235
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition drbg.h:244
Hash_DRBG(const byte *entropy=NULL, size_t entropyLength=STRENGTH, const byte *nonce=NULL, size_t nonceLength=0, const byte *personalization=NULL, size_t personalizationLength=0)
Construct a Hash DRBG.
Definition drbg.h:210
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition drbg.h:238
unsigned int SecurityStrength() const
Provides the security strength.
Definition drbg.h:223
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition drbg.h:228
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition drbg.h:225
Exception thrown when a NIST DRBG encounters an error.
Definition drbg.h:31
Interface for NIST DRBGs from SP 800-90A.
Definition drbg.h:27
virtual void IncorporateEntropy(const byte *input, size_t length)=0
Update RNG state with additional unpredictable values.
virtual unsigned int SecurityStrength() const =0
Provides the security strength.
virtual void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)=0
Update RNG state with additional unpredictable values.
virtual unsigned int MaxEntropyLength() const =0
Provides the maximum entropy size.
virtual void GenerateBlock(byte *output, size_t size)=0
Generate random array of bytes.
virtual unsigned int MinEntropyLength() const =0
Provides the minimum entropy size.
virtual void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)=0
Generate random array of bytes.
virtual unsigned int MaxBytesPerRequest() const =0
Provides the maximum size of a request to GenerateBlock.
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition drbg.h:43
virtual unsigned int MaxRequestBeforeReseed() const =0
Provides the maximum number of requests before a reseed.
virtual unsigned int MaxNonceLength() const =0
Provides the maximum nonce size.
virtual unsigned int MinNonceLength() const =0
Provides the minimum nonce size.
virtual unsigned int SeedLength() const =0
Provides the seed length.
Ensures an object is not copyable.
Definition misc.h:241
Interface for random number generators.
Definition cryptlib.h:1440
SHA-256 message digest.
Definition sha.h:65
A::pointer data()
Provides a pointer to the first element in the memory block.
Definition secblock.h:857
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
SecBlock typedef.
Definition secblock.h:1226
unsigned int word32
32-bit unsigned datatype
Definition config_int.h:72
unsigned long long word64
64-bit unsigned datatype
Definition config_int.h:101
Abstract base classes that provide a uniform interface to this library.
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition cryptlib.h:152
Classes for HMAC message authentication codes.
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition misc.h:1508
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition misc.h:657
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition misc.h:2417
Crypto++ library namespace.
Classes and functions for secure memory allocations.
Classes for SHA-1 and SHA-2 family of message digests.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition trap.h:68