blake2_mac_impl.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * Copyright 2018-2021 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_dispatch.h>
  10. #include <openssl/core_names.h>
  11. #include <openssl/params.h>
  12. #include <openssl/proverr.h>
  13. #include "prov/blake2.h"
  14. #include "internal/cryptlib.h"
  15. #include "prov/implementations.h"
  16. #include "prov/providercommon.h"
  17. /*
  18. * Forward declaration of everything 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_FUNC_mac_newctx_fn blake2_mac_new;
  23. static OSSL_FUNC_mac_dupctx_fn blake2_mac_dup;
  24. static OSSL_FUNC_mac_freectx_fn blake2_mac_free;
  25. static OSSL_FUNC_mac_gettable_ctx_params_fn blake2_gettable_ctx_params;
  26. static OSSL_FUNC_mac_get_ctx_params_fn blake2_get_ctx_params;
  27. static OSSL_FUNC_mac_settable_ctx_params_fn blake2_mac_settable_ctx_params;
  28. static OSSL_FUNC_mac_set_ctx_params_fn blake2_mac_set_ctx_params;
  29. static OSSL_FUNC_mac_init_fn blake2_mac_init;
  30. static OSSL_FUNC_mac_update_fn blake2_mac_update;
  31. static OSSL_FUNC_mac_final_fn blake2_mac_final;
  32. struct blake2_mac_data_st {
  33. BLAKE2_CTX ctx;
  34. BLAKE2_PARAM params;
  35. unsigned char key[BLAKE2_KEYBYTES];
  36. };
  37. static void *blake2_mac_new(void *unused_provctx)
  38. {
  39. struct blake2_mac_data_st *macctx;
  40. if (!ossl_prov_is_running())
  41. return NULL;
  42. macctx = OPENSSL_zalloc(sizeof(*macctx));
  43. if (macctx != NULL) {
  44. BLAKE2_PARAM_INIT(&macctx->params);
  45. /* ctx initialization is deferred to BLAKE2b_Init() */
  46. }
  47. return macctx;
  48. }
  49. static void *blake2_mac_dup(void *vsrc)
  50. {
  51. struct blake2_mac_data_st *dst;
  52. struct blake2_mac_data_st *src = vsrc;
  53. if (!ossl_prov_is_running())
  54. return NULL;
  55. dst = OPENSSL_zalloc(sizeof(*dst));
  56. if (dst == NULL)
  57. return NULL;
  58. *dst = *src;
  59. return dst;
  60. }
  61. static void blake2_mac_free(void *vmacctx)
  62. {
  63. struct blake2_mac_data_st *macctx = vmacctx;
  64. if (macctx != NULL) {
  65. OPENSSL_cleanse(macctx->key, sizeof(macctx->key));
  66. OPENSSL_free(macctx);
  67. }
  68. }
  69. static size_t blake2_mac_size(void *vmacctx)
  70. {
  71. struct blake2_mac_data_st *macctx = vmacctx;
  72. return macctx->params.digest_length;
  73. }
  74. static int blake2_setkey(struct blake2_mac_data_st *macctx,
  75. const unsigned char *key, size_t keylen)
  76. {
  77. if (keylen > BLAKE2_KEYBYTES || keylen == 0) {
  78. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
  79. return 0;
  80. }
  81. memcpy(macctx->key, key, keylen);
  82. /* Pad with zeroes at the end if required */
  83. if (keylen < BLAKE2_KEYBYTES)
  84. memset(macctx->key + keylen, 0, BLAKE2_KEYBYTES - keylen);
  85. BLAKE2_PARAM_SET_KEY_LENGTH(&macctx->params, (uint8_t)keylen);
  86. return 1;
  87. }
  88. static int blake2_mac_init(void *vmacctx, const unsigned char *key,
  89. size_t keylen, const OSSL_PARAM params[])
  90. {
  91. struct blake2_mac_data_st *macctx = vmacctx;
  92. if (!ossl_prov_is_running() || !blake2_mac_set_ctx_params(macctx, params))
  93. return 0;
  94. if (key != NULL) {
  95. if (!blake2_setkey(macctx, key, keylen))
  96. return 0;
  97. } else if (macctx->params.key_length == 0) {
  98. /* Check key has been set */
  99. ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
  100. return 0;
  101. }
  102. return BLAKE2_INIT_KEY(&macctx->ctx, &macctx->params, macctx->key);
  103. }
  104. static int blake2_mac_update(void *vmacctx,
  105. const unsigned char *data, size_t datalen)
  106. {
  107. struct blake2_mac_data_st *macctx = vmacctx;
  108. if (datalen == 0)
  109. return 1;
  110. return BLAKE2_UPDATE(&macctx->ctx, data, datalen);
  111. }
  112. static int blake2_mac_final(void *vmacctx,
  113. unsigned char *out, size_t *outl,
  114. size_t outsize)
  115. {
  116. struct blake2_mac_data_st *macctx = vmacctx;
  117. if (!ossl_prov_is_running())
  118. return 0;
  119. *outl = blake2_mac_size(macctx);
  120. return BLAKE2_FINAL(out, &macctx->ctx);
  121. }
  122. static const OSSL_PARAM known_gettable_ctx_params[] = {
  123. OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
  124. OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
  125. OSSL_PARAM_END
  126. };
  127. static const OSSL_PARAM *blake2_gettable_ctx_params(ossl_unused void *ctx,
  128. ossl_unused void *provctx)
  129. {
  130. return known_gettable_ctx_params;
  131. }
  132. static int blake2_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
  133. {
  134. OSSL_PARAM *p;
  135. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL
  136. && !OSSL_PARAM_set_size_t(p, blake2_mac_size(vmacctx)))
  137. return 0;
  138. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL
  139. && !OSSL_PARAM_set_size_t(p, BLAKE2_BLOCKBYTES))
  140. return 0;
  141. return 1;
  142. }
  143. static const OSSL_PARAM known_settable_ctx_params[] = {
  144. OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
  145. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
  146. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
  147. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0),
  148. OSSL_PARAM_END
  149. };
  150. static const OSSL_PARAM *blake2_mac_settable_ctx_params(
  151. ossl_unused void *ctx, ossl_unused void *p_ctx)
  152. {
  153. return known_settable_ctx_params;
  154. }
  155. /*
  156. * ALL parameters should be set before init().
  157. */
  158. static int blake2_mac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
  159. {
  160. struct blake2_mac_data_st *macctx = vmacctx;
  161. const OSSL_PARAM *p;
  162. if (params == NULL)
  163. return 1;
  164. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
  165. size_t size;
  166. if (!OSSL_PARAM_get_size_t(p, &size)
  167. || size < 1
  168. || size > BLAKE2_OUTBYTES) {
  169. ERR_raise(ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH);
  170. return 0;
  171. }
  172. BLAKE2_PARAM_SET_DIGEST_LENGTH(&macctx->params, (uint8_t)size);
  173. }
  174. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL
  175. && !blake2_setkey(macctx, p->data, p->data_size))
  176. return 0;
  177. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
  178. != NULL) {
  179. /*
  180. * The OSSL_PARAM API doesn't provide direct pointer use, so we
  181. * must handle the OSSL_PARAM structure ourselves here
  182. */
  183. if (p->data_size > BLAKE2_PERSONALBYTES) {
  184. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
  185. return 0;
  186. }
  187. BLAKE2_PARAM_SET_PERSONAL(&macctx->params, p->data, p->data_size);
  188. }
  189. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SALT)) != NULL) {
  190. /*
  191. * The OSSL_PARAM API doesn't provide direct pointer use, so we
  192. * must handle the OSSL_PARAM structure ourselves here as well
  193. */
  194. if (p->data_size > BLAKE2_SALTBYTES) {
  195. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
  196. return 0;
  197. }
  198. BLAKE2_PARAM_SET_SALT(&macctx->params, p->data, p->data_size);
  199. }
  200. return 1;
  201. }
  202. const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = {
  203. { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))blake2_mac_new },
  204. { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))blake2_mac_dup },
  205. { OSSL_FUNC_MAC_FREECTX, (void (*)(void))blake2_mac_free },
  206. { OSSL_FUNC_MAC_INIT, (void (*)(void))blake2_mac_init },
  207. { OSSL_FUNC_MAC_UPDATE, (void (*)(void))blake2_mac_update },
  208. { OSSL_FUNC_MAC_FINAL, (void (*)(void))blake2_mac_final },
  209. { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
  210. (void (*)(void))blake2_gettable_ctx_params },
  211. { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))blake2_get_ctx_params },
  212. { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
  213. (void (*)(void))blake2_mac_settable_ctx_params },
  214. { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))blake2_mac_set_ctx_params },
  215. OSSL_DISPATCH_END
  216. };