Crypto++  8.2
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 
17 NAMESPACE_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 {
26 public:
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 
35 public:
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 
139 protected:
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
162 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
163 class Hash_DRBG : public NIST_DRBG, public NotCopyable
164 {
165 public:
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 
238 protected:
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 
253 private:
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
279 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
280 class HMAC_DRBG : public NIST_DRBG, public NotCopyable
281 {
282 public:
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 
355 protected:
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 
369 private:
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)
383 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
384 void 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)
412 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
413 void 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)
439 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
440 void 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)
533 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
534 void 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)
565 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
566 void 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)
592 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
593 void 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)
614 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
615 void 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)
650 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
651 void 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 
700 NAMESPACE_END
701 
702 #endif // CRYPTOPP_NIST_DRBG_H
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
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:340
unsigned int SecurityStrength() const
Provides the security strength.
Definition: drbg.h:214
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
SHA-256 message digest.
Definition: sha.h:64
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:221
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition: misc.h:1226
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:332
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
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:333
Abstract base classes that provide a uniform interface to this library.
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:349
Interface for random number generators.
Definition: cryptlib.h:1383
SecBlock<byte> typedef.
Definition: secblock.h:1058
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:216
Classes and functions for secure memory allocations.
Classes for HMAC message authentication codes.
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition: drbg.h:218
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:223
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
Exception thrown when a NIST DRBG encounters an error.
Definition: drbg.h:28
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:232
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2113
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:229
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:280
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition: drbg.h:335
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:215
byte order is big-endian
Definition: cryptlib.h:147
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:220
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:567
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
Classes for SHA-1 and SHA-2 family of message digests.
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:163
Interface for NIST DRBGs from SP 800-90A.
Definition: drbg.h:24
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:338
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:217
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:219
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:337
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:334
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: drbg.h:41
Crypto++ library namespace.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:235
Ensures an object is not copyable.
Definition: misc.h:200
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:352
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:336
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