You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

235 lines
6.7 KiB

  1. /**
  2. * @file shake.h
  3. * @copyright
  4. * Based on CC0 code by David Leon Gil, 2015 \n
  5. * Copyright (c) 2015 Cryptography Research, Inc. \n
  6. * Released under the MIT License. See LICENSE.txt for license information.
  7. * @author Mike Hamburg
  8. * @brief SHA-3-n and SHAKE-n instances.
  9. * @warning EXPERIMENTAL! The names, parameter orders etc are likely to change.
  10. */
  11. #ifndef __SHAKE_H__
  12. #define __SHAKE_H__
  13. #include <stdint.h>
  14. #include <sys/types.h>
  15. /* TODO: unify with other headers (maybe all into one??); add nonnull attributes */
  16. #define API_VIS __attribute__((visibility("default")))
  17. #define WARN_UNUSED __attribute__((warn_unused_result))
  18. /* TODO: different containing structs for each primitive? */
  19. #ifndef INTERNAL_SPONGE_STRUCT
  20. typedef struct keccak_sponge_s {
  21. uint64_t opaque[26];
  22. } keccak_sponge_t[1];
  23. struct kparams_s;
  24. #endif
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. /**
  29. * @brief Initialize a sponge context object.
  30. * @param [out] sponge The object to initialize.
  31. * @param [in] params The sponge's parameter description.
  32. */
  33. void sponge_init (
  34. keccak_sponge_t sponge,
  35. const struct kparams_s *params
  36. ) API_VIS;
  37. /**
  38. * @brief Absorb data into a SHA3 or SHAKE hash context.
  39. * @param [inout] sponge The context.
  40. * @param [in] in The input data.
  41. * @param [in] len The input data's length in bytes.
  42. */
  43. void sha3_update (
  44. struct keccak_sponge_s * __restrict__ sponge,
  45. const uint8_t *in,
  46. size_t len
  47. ) API_VIS;
  48. /**
  49. * @brief Squeeze output data from a SHA3 or SHAKE hash context.
  50. * This does not destroy or re-initialize the hash context, and
  51. * sha3 output can be called more times.
  52. *
  53. * @param [inout] sponge The context.
  54. * @param [out] in The output data.
  55. * @param [in] len The requested output data length in bytes.
  56. */
  57. void sha3_output (
  58. keccak_sponge_t sponge,
  59. uint8_t * __restrict__ out,
  60. size_t len
  61. ) API_VIS;
  62. /**
  63. * @brief Destroy a SHA3 or SHAKE sponge context by overwriting it with 0.
  64. * @param [out] sponge The context.
  65. */
  66. void sponge_destroy (
  67. keccak_sponge_t sponge
  68. ) API_VIS;
  69. /**
  70. * @brief Hash (in) to (out)
  71. * @param [in] in The input data.
  72. * @param [in] inlen The length of the input data.
  73. * @param [out] out A buffer for the output data.
  74. * @param [in] outlen The length of the output data.
  75. * @param [in] params The parameters of the sponge hash.
  76. */
  77. void sponge_hash (
  78. const uint8_t *in,
  79. size_t inlen,
  80. uint8_t *out,
  81. size_t outlen,
  82. const struct kparams_s *params
  83. ) API_VIS;
  84. /* TODO: expand/doxygenate individual SHAKE/SHA3 instances? */
  85. #define DECSHAKE(n) \
  86. extern const struct kparams_s SHAKE##n##_params_s API_VIS; \
  87. static inline void shake##n##_init(keccak_sponge_t sponge) { \
  88. sponge_init(sponge, &SHAKE##n##_params_s); \
  89. } \
  90. static inline void shake##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
  91. sha3_update(sponge, in, inlen); \
  92. } \
  93. static inline void shake##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
  94. sha3_output(sponge, out, outlen); \
  95. sponge_init(sponge, &SHAKE##n##_params_s); \
  96. } \
  97. static inline void shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
  98. sponge_hash(in,inlen,out,outlen,&SHAKE##n##_params_s); \
  99. } \
  100. static inline void shake##n##_destroy( keccak_sponge_t sponge ) { \
  101. sponge_destroy(sponge); \
  102. }
  103. #define DECSHA3(n) \
  104. extern const struct kparams_s SHA3_##n##_params_s API_VIS; \
  105. static inline void sha3_##n##_init(keccak_sponge_t sponge) { \
  106. sponge_init(sponge, &SHA3_##n##_params_s); \
  107. } \
  108. static inline void sha3_##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
  109. sha3_update(sponge, in, inlen); \
  110. } \
  111. static inline void sha3_##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
  112. sha3_output(sponge, out, outlen); \
  113. sponge_init(sponge, &SHA3_##n##_params_s); \
  114. } \
  115. static inline void sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
  116. sponge_hash(in,inlen,out,outlen,&SHA3_##n##_params_s); \
  117. } \
  118. static inline void sha3_##n##_destroy( keccak_sponge_t sponge ) { \
  119. sponge_destroy(sponge); \
  120. }
  121. DECSHAKE(128)
  122. DECSHAKE(256)
  123. DECSHA3(224)
  124. DECSHA3(256)
  125. DECSHA3(384)
  126. DECSHA3(512)
  127. /**
  128. * @brief Initialize a sponge-based CSPRNG from a buffer.
  129. *
  130. * @param [out] sponge The sponge object.
  131. * @param [in] in The initial data.
  132. * @param [in] len The length of the initial data.
  133. * @param [in] deterministic If zero, allow RNG to stir in nondeterministic
  134. * data from RDRAND or RDTSC.
  135. */
  136. void spongerng_init_from_buffer (
  137. keccak_sponge_t sponge,
  138. const uint8_t * __restrict__ in,
  139. size_t len,
  140. int deterministic
  141. ) API_VIS;
  142. /* FIXME!! This interface has the opposite retval convention from other functions
  143. * in the library. (0=success). Should they be harmonized?
  144. */
  145. /**
  146. * @brief Initialize a sponge-based CSPRNG from a file.
  147. *
  148. * @param [out] sponge The sponge object.
  149. * @param [in] file A name of a file containing initial data.
  150. * @param [in] len The length of the initial data. Must be positive.
  151. * @param [in] deterministic If zero, allow RNG to stir in nondeterministic
  152. * data from RDRAND or RDTSC.
  153. *
  154. * @retval 0 Success.
  155. * @retval positive An error has occurred, and this was the errno.
  156. * @retval -1 An unknown error has occurred.
  157. * @retval -2 len was 0.
  158. */
  159. int spongerng_init_from_file (
  160. keccak_sponge_t sponge,
  161. const char *file,
  162. size_t len,
  163. int deterministic
  164. ) API_VIS WARN_UNUSED;
  165. /* FIXME!! This interface has the opposite retval convention from other functions
  166. * in the library. (0=success). Should they be harmonized?
  167. */
  168. /**
  169. * @brief Initialize a nondeterministic sponge-based CSPRNG from /dev/urandom.
  170. *
  171. * @param [out] sponge The sponge object.
  172. *
  173. * @retval 0 Success.
  174. * @retval positive An error has occurred, and this was the errno.
  175. * @retval -1 An unknown error has occurred.
  176. */
  177. int spongerng_init_from_dev_urandom (
  178. keccak_sponge_t sponge
  179. ) API_VIS WARN_UNUSED;
  180. /**
  181. * @brief Output bytes from a sponge-based CSPRNG.
  182. *
  183. * @param [inout] sponge The sponge object.
  184. * @param [out] out The output buffer.
  185. * @param [in] out The output buffer's length.
  186. */
  187. void spongerng_next (
  188. keccak_sponge_t sponge,
  189. uint8_t * __restrict__ out,
  190. size_t len
  191. ) API_VIS;
  192. /**
  193. * @brief Stir entropy data into a sponge-based CSPRNG from a buffer.
  194. *
  195. * @param [out] sponge The sponge object.
  196. * @param [in] in The entropy data.
  197. * @param [in] len The length of the initial data.
  198. */
  199. void spongerng_stir (
  200. keccak_sponge_t sponge,
  201. const uint8_t * __restrict__ in,
  202. size_t len
  203. ) API_VIS;
  204. #ifdef __cplusplus
  205. } /* extern "C" */
  206. #endif
  207. #undef API_VIS
  208. #undef WARN_UNUSED
  209. #endif /* __SHAKE_H__ */