siphash_prov.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright 2018-2022 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 <string.h>
  10. #include <openssl/core_dispatch.h>
  11. #include <openssl/core_names.h>
  12. #include <openssl/params.h>
  13. #include <openssl/evp.h>
  14. #include <openssl/err.h>
  15. #include <openssl/proverr.h>
  16. #include "crypto/siphash.h"
  17. #include "prov/implementations.h"
  18. #include "prov/providercommon.h"
  19. /*
  20. * Forward declaration of everything implemented here. This is not strictly
  21. * necessary for the compiler, but provides an assurance that the signatures
  22. * of the functions in the dispatch table are correct.
  23. */
  24. static OSSL_FUNC_mac_newctx_fn siphash_new;
  25. static OSSL_FUNC_mac_dupctx_fn siphash_dup;
  26. static OSSL_FUNC_mac_freectx_fn siphash_free;
  27. static OSSL_FUNC_mac_gettable_ctx_params_fn siphash_gettable_ctx_params;
  28. static OSSL_FUNC_mac_get_ctx_params_fn siphash_get_ctx_params;
  29. static OSSL_FUNC_mac_settable_ctx_params_fn siphash_settable_ctx_params;
  30. static OSSL_FUNC_mac_set_ctx_params_fn siphash_set_params;
  31. static OSSL_FUNC_mac_init_fn siphash_init;
  32. static OSSL_FUNC_mac_update_fn siphash_update;
  33. static OSSL_FUNC_mac_final_fn siphash_final;
  34. struct siphash_data_st {
  35. void *provctx;
  36. SIPHASH siphash; /* Siphash data */
  37. SIPHASH sipcopy; /* Siphash data copy for reinitialization */
  38. unsigned int crounds, drounds;
  39. };
  40. static unsigned int crounds(struct siphash_data_st *ctx)
  41. {
  42. return ctx->crounds != 0 ? ctx->crounds : SIPHASH_C_ROUNDS;
  43. }
  44. static unsigned int drounds(struct siphash_data_st *ctx)
  45. {
  46. return ctx->drounds != 0 ? ctx->drounds : SIPHASH_D_ROUNDS;
  47. }
  48. static void *siphash_new(void *provctx)
  49. {
  50. struct siphash_data_st *ctx;
  51. if (!ossl_prov_is_running())
  52. return NULL;
  53. ctx = OPENSSL_zalloc(sizeof(*ctx));
  54. if (ctx != NULL)
  55. ctx->provctx = provctx;
  56. return ctx;
  57. }
  58. static void siphash_free(void *vmacctx)
  59. {
  60. OPENSSL_free(vmacctx);
  61. }
  62. static void *siphash_dup(void *vsrc)
  63. {
  64. struct siphash_data_st *ssrc = vsrc;
  65. struct siphash_data_st *sdst;
  66. if (!ossl_prov_is_running())
  67. return NULL;
  68. sdst = OPENSSL_malloc(sizeof(*sdst));
  69. if (sdst == NULL)
  70. return NULL;
  71. *sdst = *ssrc;
  72. return sdst;
  73. }
  74. static size_t siphash_size(void *vmacctx)
  75. {
  76. struct siphash_data_st *ctx = vmacctx;
  77. return SipHash_hash_size(&ctx->siphash);
  78. }
  79. static int siphash_setkey(struct siphash_data_st *ctx,
  80. const unsigned char *key, size_t keylen)
  81. {
  82. int ret;
  83. if (keylen != SIPHASH_KEY_SIZE)
  84. return 0;
  85. ret = SipHash_Init(&ctx->siphash, key, crounds(ctx), drounds(ctx));
  86. if (ret)
  87. ctx->sipcopy = ctx->siphash;
  88. return ret;
  89. }
  90. static int siphash_init(void *vmacctx, const unsigned char *key, size_t keylen,
  91. const OSSL_PARAM params[])
  92. {
  93. struct siphash_data_st *ctx = vmacctx;
  94. if (!ossl_prov_is_running() || !siphash_set_params(ctx, params))
  95. return 0;
  96. /*
  97. * Without a key, there is not much to do here,
  98. * The actual initialization happens through controls.
  99. */
  100. if (key == NULL) {
  101. ctx->siphash = ctx->sipcopy;
  102. return 1;
  103. }
  104. return siphash_setkey(ctx, key, keylen);
  105. }
  106. static int siphash_update(void *vmacctx, const unsigned char *data,
  107. size_t datalen)
  108. {
  109. struct siphash_data_st *ctx = vmacctx;
  110. if (datalen == 0)
  111. return 1;
  112. SipHash_Update(&ctx->siphash, data, datalen);
  113. return 1;
  114. }
  115. static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl,
  116. size_t outsize)
  117. {
  118. struct siphash_data_st *ctx = vmacctx;
  119. size_t hlen = siphash_size(ctx);
  120. if (!ossl_prov_is_running() || outsize < hlen)
  121. return 0;
  122. *outl = hlen;
  123. return SipHash_Final(&ctx->siphash, out, hlen);
  124. }
  125. static const OSSL_PARAM *siphash_gettable_ctx_params(ossl_unused void *ctx,
  126. ossl_unused void *provctx)
  127. {
  128. static const OSSL_PARAM known_gettable_ctx_params[] = {
  129. OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
  130. OSSL_PARAM_uint(OSSL_MAC_PARAM_C_ROUNDS, NULL),
  131. OSSL_PARAM_uint(OSSL_MAC_PARAM_D_ROUNDS, NULL),
  132. OSSL_PARAM_END
  133. };
  134. return known_gettable_ctx_params;
  135. }
  136. static int siphash_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
  137. {
  138. struct siphash_data_st *ctx = vmacctx;
  139. OSSL_PARAM *p;
  140. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL
  141. && !OSSL_PARAM_set_size_t(p, siphash_size(vmacctx)))
  142. return 0;
  143. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_C_ROUNDS)) != NULL
  144. && !OSSL_PARAM_set_uint(p, crounds(ctx)))
  145. return 0;
  146. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_D_ROUNDS)) != NULL
  147. && !OSSL_PARAM_set_uint(p, drounds(ctx)))
  148. return 0;
  149. return 1;
  150. }
  151. static const OSSL_PARAM *siphash_settable_ctx_params(ossl_unused void *ctx,
  152. void *provctx)
  153. {
  154. static const OSSL_PARAM known_settable_ctx_params[] = {
  155. OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
  156. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
  157. OSSL_PARAM_uint(OSSL_MAC_PARAM_C_ROUNDS, NULL),
  158. OSSL_PARAM_uint(OSSL_MAC_PARAM_D_ROUNDS, NULL),
  159. OSSL_PARAM_END
  160. };
  161. return known_settable_ctx_params;
  162. }
  163. static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params)
  164. {
  165. struct siphash_data_st *ctx = vmacctx;
  166. const OSSL_PARAM *p = NULL;
  167. size_t size;
  168. if (params == NULL)
  169. return 1;
  170. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
  171. if (!OSSL_PARAM_get_size_t(p, &size)
  172. || !SipHash_set_hash_size(&ctx->siphash, size)
  173. || !SipHash_set_hash_size(&ctx->sipcopy, size))
  174. return 0;
  175. }
  176. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_C_ROUNDS)) != NULL
  177. && !OSSL_PARAM_get_uint(p, &ctx->crounds))
  178. return 0;
  179. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_D_ROUNDS)) != NULL
  180. && !OSSL_PARAM_get_uint(p, &ctx->drounds))
  181. return 0;
  182. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL)
  183. if (p->data_type != OSSL_PARAM_OCTET_STRING
  184. || !siphash_setkey(ctx, p->data, p->data_size))
  185. return 0;
  186. return 1;
  187. }
  188. const OSSL_DISPATCH ossl_siphash_functions[] = {
  189. { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new },
  190. { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup },
  191. { OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free },
  192. { OSSL_FUNC_MAC_INIT, (void (*)(void))siphash_init },
  193. { OSSL_FUNC_MAC_UPDATE, (void (*)(void))siphash_update },
  194. { OSSL_FUNC_MAC_FINAL, (void (*)(void))siphash_final },
  195. { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
  196. (void (*)(void))siphash_gettable_ctx_params },
  197. { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))siphash_get_ctx_params },
  198. { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
  199. (void (*)(void))siphash_settable_ctx_params },
  200. { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))siphash_set_params },
  201. { 0, NULL }
  202. };