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