sha3_prov.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/core_names.h>
  10. #include <string.h>
  11. #include <openssl/crypto.h>
  12. #include <openssl/evp.h>
  13. #include <openssl/params.h>
  14. #include "internal/sha3.h"
  15. #include "internal/core_mkdigest.h"
  16. #include "internal/provider_algs.h"
  17. /*
  18. * Forward declaration of any unique methods implemented here. This is not strictly
  19. * necessary for the compiler, but provides an assurance that the signatures
  20. * of the functions in the dispatch table are correct.
  21. */
  22. static OSSL_OP_digest_init_fn keccak_init;
  23. static OSSL_OP_digest_update_fn keccak_update;
  24. static OSSL_OP_digest_final_fn keccak_final;
  25. static OSSL_OP_digest_freectx_fn keccak_freectx;
  26. static OSSL_OP_digest_dupctx_fn keccak_dupctx;
  27. static OSSL_OP_digest_set_params_fn shake_set_params;
  28. static sha3_absorb_fn generic_sha3_absorb;
  29. static sha3_final_fn generic_sha3_final;
  30. #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
  31. /*
  32. * IBM S390X support
  33. */
  34. # include "s390x_arch.h"
  35. # define S390_SHA3 1
  36. # define S390_SHA3_CAPABLE(name) \
  37. ((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \
  38. (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
  39. #endif
  40. static int keccak_init(void *vctx)
  41. {
  42. /* The newctx() handles most of the ctx fixed setup. */
  43. sha3_reset((KECCAK1600_CTX *)vctx);
  44. return 1;
  45. }
  46. static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
  47. {
  48. KECCAK1600_CTX *ctx = vctx;
  49. const size_t bsz = ctx->block_size;
  50. size_t num, rem;
  51. if (len == 0)
  52. return 1;
  53. /* Is there anything in the buffer already ? */
  54. if ((num = ctx->bufsz) != 0) {
  55. /* Calculate how much space is left in the buffer */
  56. rem = bsz - num;
  57. /* If the new input does not fill the buffer then just add it */
  58. if (len < rem) {
  59. memcpy(ctx->buf + num, inp, len);
  60. ctx->bufsz += len;
  61. return 1;
  62. }
  63. /* otherwise fill up the buffer and absorb the buffer */
  64. memcpy(ctx->buf + num, inp, rem);
  65. /* Update the input pointer */
  66. inp += rem;
  67. len -= rem;
  68. ctx->meth.absorb(ctx, ctx->buf, bsz);
  69. ctx->bufsz = 0;
  70. }
  71. /* Absorb the input - rem = leftover part of the input < blocksize) */
  72. rem = ctx->meth.absorb(ctx, inp, len);
  73. /* Copy the leftover bit of the input into the buffer */
  74. if (rem) {
  75. memcpy(ctx->buf, inp + len - rem, rem);
  76. ctx->bufsz = rem;
  77. }
  78. return 1;
  79. }
  80. static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
  81. size_t outsz)
  82. {
  83. int ret;
  84. KECCAK1600_CTX *ctx = vctx;
  85. ret = ctx->meth.final(out, ctx);
  86. *outl = ctx->md_size;
  87. return ret;
  88. }
  89. /*-
  90. * Generic software version of the absorb() and final().
  91. */
  92. static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)
  93. {
  94. KECCAK1600_CTX *ctx = vctx;
  95. return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
  96. }
  97. static int generic_sha3_final(unsigned char *md, void *vctx)
  98. {
  99. return sha3_final(md, (KECCAK1600_CTX *)vctx);
  100. }
  101. static PROV_SHA3_METHOD sha3_generic_md =
  102. {
  103. generic_sha3_absorb,
  104. generic_sha3_final
  105. };
  106. #if defined(S390_SHA3)
  107. static sha3_absorb_fn s390x_sha3_absorb;
  108. static sha3_final_fn s390x_sha3_final;
  109. static sha3_final_fn s390x_shake_final;
  110. /*-
  111. * The platform specific parts of the absorb() and final() for S390X.
  112. */
  113. static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)
  114. {
  115. KECCAK1600_CTX *ctx = vctx;
  116. size_t rem = len % ctx->block_size;
  117. s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
  118. return rem;
  119. }
  120. static int s390x_sha3_final(unsigned char *md, void *vctx)
  121. {
  122. KECCAK1600_CTX *ctx = vctx;
  123. s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A);
  124. memcpy(md, ctx->A, ctx->md_size);
  125. }
  126. static int s390x_shake_final(unsigned char *md, void *vctx)
  127. {
  128. KECCAK1600_CTX *ctx = vctx;
  129. s390x_klmd(ctx->buf, ctx->bufsz, md, ctx->md_size, ctx->pad, ctx->A);
  130. return 1;
  131. }
  132. static PROV_SHA3_METHOD sha3_s390x_md =
  133. {
  134. s390x_sha3_absorb,
  135. s390x_sha3_final
  136. };
  137. static PROV_SHA3_METHOD shake_s390x_md =
  138. {
  139. s390x_sha3_absorb,
  140. s390x_shake_final
  141. };
  142. # define SHA3_SET_MD(uname, typ) \
  143. if (S390_SHA3_CAPABLE(uname)) { \
  144. ctx->pad = S390X_##uname; \
  145. ctx->meth = typ##_s390x_md; \
  146. } else { \
  147. ctx->meth = sha3_generic_md; \
  148. }
  149. #else
  150. # define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
  151. #endif /* S390_SHA3 */
  152. #define SHA3_newctx(typ, uname, name, bitlen, pad) \
  153. static OSSL_OP_digest_newctx_fn name##_newctx; \
  154. static void *name##_newctx(void *provctx) \
  155. { \
  156. KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
  157. \
  158. if (ctx == NULL) \
  159. return NULL; \
  160. sha3_init(ctx, pad, bitlen); \
  161. SHA3_SET_MD(name, typ) \
  162. return ctx; \
  163. }
  164. #define KMAC_newctx(uname, bitlen, pad) \
  165. static OSSL_OP_digest_newctx_fn uname##_newctx; \
  166. static void *uname##_newctx(void *provctx) \
  167. { \
  168. KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
  169. \
  170. if (ctx == NULL) \
  171. return NULL; \
  172. keccak_kmac_init(ctx, pad, bitlen); \
  173. ctx->meth = sha3_generic_md; \
  174. return ctx; \
  175. }
  176. #define OSSL_FUNC_SHA3_DIGEST(name, bitlen, dgstsize, stparams) \
  177. static OSSL_OP_digest_size_fn name##_size; \
  178. static OSSL_OP_digest_block_size_fn name##_block_size; \
  179. static size_t name##_block_size(void) \
  180. { \
  181. return SHA3_BLOCKSIZE(bitlen); \
  182. } \
  183. static size_t name##_size(void) \
  184. { \
  185. return dgstsize; \
  186. } \
  187. const OSSL_DISPATCH name##_functions[] = { \
  188. { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \
  189. { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \
  190. { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \
  191. { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \
  192. { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \
  193. { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \
  194. { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))name##_size }, \
  195. { OSSL_FUNC_DIGEST_BLOCK_SIZE, (void (*)(void))name##_block_size }, \
  196. { OSSL_FUNC_DIGEST_SET_PARAMS, (void (*)(void))stparams },\
  197. OSSL_FUNC_DIGEST_CONSTRUCT_END
  198. static void keccak_freectx(void *vctx)
  199. {
  200. KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
  201. OPENSSL_clear_free(ctx, sizeof(*ctx));
  202. }
  203. static void *keccak_dupctx(void *ctx)
  204. {
  205. KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
  206. KECCAK1600_CTX *ret = OPENSSL_malloc(sizeof(*ret));
  207. *ret = *in;
  208. return ret;
  209. }
  210. static int shake_set_params(void *vctx, const OSSL_PARAM params[])
  211. {
  212. const OSSL_PARAM *p;
  213. KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
  214. if (ctx != NULL && params != NULL) {
  215. p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);
  216. if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size))
  217. return 0;
  218. return 1;
  219. }
  220. return 0; /* Null Parameter */
  221. }
  222. #define SHA3(bitlen) \
  223. SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \
  224. OSSL_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, SHA3_MDSIZE(bitlen), NULL)
  225. #define SHAKE(bitlen) \
  226. SHA3_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \
  227. OSSL_FUNC_SHA3_DIGEST(shake_##bitlen, bitlen, SHA3_MDSIZE(bitlen), \
  228. shake_set_params)
  229. #define KMAC(bitlen) \
  230. KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \
  231. OSSL_FUNC_SHA3_DIGEST(keccak_kmac_##bitlen, bitlen, KMAC_MDSIZE(bitlen), \
  232. shake_set_params)
  233. SHA3(224)
  234. SHA3(256)
  235. SHA3(384)
  236. SHA3(512)
  237. SHAKE(128)
  238. SHAKE(256)
  239. KMAC(128)
  240. KMAC(256)