drbg.h 34 KB

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