drbg.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * cifra - embedded cryptography library
  3. * Written in 2016 by Joseph Birr-Pixton <jpixton@gmail.com>
  4. *
  5. * To the extent possible under law, the author(s) have dedicated all
  6. * copyright and related and neighboring rights to this software to the
  7. * public domain worldwide. This software is distributed without any
  8. * warranty.
  9. *
  10. * You should have received a copy of the CC0 Public Domain Dedication
  11. * along with this software. If not, see
  12. * <http://creativecommons.org/publicdomain/zero/1.0/>.
  13. */
  14. #ifndef DRBG_H
  15. #define DRBG_H
  16. #include <stddef.h>
  17. #include <stdint.h>
  18. #include "chash.h"
  19. #include "hmac.h"
  20. /**
  21. * Hash_DRBG
  22. * =========
  23. * This is Hash_DRBG from SP800-90A rev 1, with SHA256 as
  24. * the underlying hash function.
  25. *
  26. * This generator enforces a `reseed_interval` of 2^32-1:
  27. * use :c:func:`cf_hash_drbg_sha256_needs_reseed` to check
  28. * whether you need to reseed before use, and reseed using
  29. * :c:func:`cf_hash_drbg_sha256_reseed`. If you try to use
  30. * the generator when it thinks it needs reseeding, it will
  31. * call `abort`.
  32. *
  33. * Internally it enforces a `max_number_of_bits_per_request`
  34. * of 2^19 bits. It sorts out chunking up multiple requests
  35. * for you though, so feel free to ask for more than 2^16 bytes
  36. * at a time. If you provide additional input when doing that,
  37. * it is added only once, on the first subrequest.
  38. *
  39. * It does not enforce any `max_length` or
  40. * `max_personalization_string_length`.
  41. */
  42. /* .. c:type:: cf_hash_drbg_sha256
  43. * Hash_DRBG with SHA256 context.
  44. *
  45. * .. c:member:: cf_hash_drbg_sha256.V
  46. * Current internal state.
  47. *
  48. * .. c:member:: cf_hash_drbg_sha256.C
  49. * Current update offset.
  50. *
  51. * .. c:member:: cf_hash_drbg_sha256.reseed_counter
  52. * Current number of times entropy has been extracted from
  53. * generator.
  54. */
  55. typedef struct
  56. {
  57. uint8_t V[440/8];
  58. uint8_t C[440/8];
  59. uint32_t reseed_counter;
  60. } cf_hash_drbg_sha256;
  61. /* .. c:function:: $DECL
  62. * Initialises the generator state `ctx`, using the provided `entropy`,
  63. * `nonce` and personalisation string `persn`.
  64. */
  65. extern void cf_hash_drbg_sha256_init(cf_hash_drbg_sha256 *ctx,
  66. const void *entropy, size_t nentropy,
  67. const void *nonce, size_t nnonce,
  68. const void *persn, size_t npersn);
  69. /* .. c:function:: $DECL
  70. * Returns non-zero if the generator needs reseeding. If
  71. * this function returns non-zero, the next :c:func:`cf_hash_drbg_sha256_gen`
  72. * or :c:func:`cf_hash_drbg_sha256_gen_additional` call will call `abort`.
  73. */
  74. extern uint32_t cf_hash_drbg_sha256_needs_reseed(const cf_hash_drbg_sha256 *ctx);
  75. /* .. c:function:: $DECL
  76. * Reseeds the generator with the given `entropy` and additional data `addnl`.
  77. */
  78. extern void cf_hash_drbg_sha256_reseed(cf_hash_drbg_sha256 *ctx,
  79. const void *entropy, size_t nentropy,
  80. const void *addnl, size_t naddnl);
  81. /* .. c:function:: $DECL
  82. * Generates pseudo-random output, writing `nout` bytes at `out`.
  83. * This function aborts if the generator needs seeding.
  84. */
  85. extern void cf_hash_drbg_sha256_gen(cf_hash_drbg_sha256 *ctx,
  86. void *out, size_t nout);
  87. /* .. c:function:: $DECL
  88. * Generates pseudo-random output, writing `nout` bytes at `out`.
  89. * At the same time, `addnl` is input to the generator as further
  90. * entropy.
  91. * This function aborts if the generator needs seeding.
  92. */
  93. extern void cf_hash_drbg_sha256_gen_additional(cf_hash_drbg_sha256 *ctx,
  94. const void *addnl, size_t naddnl,
  95. void *out, size_t nout);
  96. /**
  97. * HMAC_DRBG
  98. * =========
  99. * This is HMAC_DRBG from SP800-90a r1 with any hash function.
  100. *
  101. * This generator enforces a `reseed_interval` of 2^32-1:
  102. * use :c:func:`cf_hmac_drbg_needs_reseed` to check whether
  103. * you need to reseed before use, and reseed using
  104. * :c:func:`cf_hmac_drbg_reseed`. If you try to use the
  105. * generator when it thinks it needs reseeding, it will
  106. * call `abort`.
  107. *
  108. * Internally it enforces a `max_number_of_bits_per_request`
  109. * of 2^19 bits. It sorts out chunking up multiple requests
  110. * for you though, so feel free to ask for more than 2^16 bytes
  111. * at a time. If you provide additional input when doing that,
  112. * it is added only once, on the first subrequest.
  113. *
  114. * It does not enforce any `max_length` or
  115. * `max_personalization_string_length`.
  116. */
  117. /* .. c:type:: cf_hmac_drbg
  118. * HMAC_DRBG context.
  119. *
  120. * .. c:member:: cf_hmac_drbg.V
  121. * Current internal state.
  122. *
  123. * .. c:member:: cf_hmac_drbg.hmac
  124. * Current HMAC context, with key scheduled in it.
  125. *
  126. * .. c:member:: cf_hmac_drbg.reseed_counter
  127. * Current number of times entropy has been extracted from
  128. * generator.
  129. */
  130. typedef struct
  131. {
  132. uint8_t V[CF_MAXHASH];
  133. cf_hmac_ctx hmac; /* pristine context with key scheduled */
  134. uint32_t reseed_counter;
  135. } cf_hmac_drbg;
  136. /* .. c:function:: $DECL
  137. * Initialises the generator state `ctx`, using the provided `entropy`,
  138. * `nonce` and personalisation string `persn`.
  139. */
  140. extern void cf_hmac_drbg_init(cf_hmac_drbg *ctx,
  141. const cf_chash *hash,
  142. const void *entropy, size_t nentropy,
  143. const void *nonce, size_t nnonce,
  144. const void *persn, size_t npersn);
  145. /* .. c:function:: $DECL
  146. * Returns non-zero if the generator needs reseeding. If
  147. * this function returns non-zero, the next :c:func:`cf_hmac_drbg_gen`
  148. * or :c:func:`cf_hmac_drbg_gen_additional` call will call `abort`.
  149. */
  150. extern uint32_t cf_hmac_drbg_needs_reseed(const cf_hmac_drbg *ctx);
  151. /* .. c:function:: $DECL
  152. * Reseeds the generator with the given `entropy` and additional data
  153. * `addnl`.
  154. */
  155. extern void cf_hmac_drbg_reseed(cf_hmac_drbg *ctx,
  156. const void *entropy, size_t nentropy,
  157. const void *addnl, size_t naddnl);
  158. /* .. c:function:: $DECL
  159. * Generates pseudo-random output, writing `nout` bytes at `out`.
  160. * This function aborts if the generator needs seeding.
  161. */
  162. extern void cf_hmac_drbg_gen(cf_hmac_drbg *ctx,
  163. void *out, size_t nout);
  164. /* .. c:function:: $DECL
  165. * Generates pseudo-random output, writing `nout` bytes at `out`.
  166. * At the same time, `addnl` is input to the generator as further
  167. * entropy.
  168. * This function aborts if the generator needs seeding.
  169. */
  170. extern void cf_hmac_drbg_gen_additional(cf_hmac_drbg *ctx,
  171. const void *addnl, size_t naddnl,
  172. void *out, size_t nout);
  173. #endif