blake2_mac_impl.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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_END
  125. };
  126. static const OSSL_PARAM *blake2_gettable_ctx_params(ossl_unused void *ctx,
  127. ossl_unused void *provctx)
  128. {
  129. return known_gettable_ctx_params;
  130. }
  131. static int blake2_get_ctx_params(void *vmacctx, OSSL_PARAM params[])
  132. {
  133. OSSL_PARAM *p;
  134. if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL)
  135. return OSSL_PARAM_set_size_t(p, blake2_mac_size(vmacctx));
  136. return 1;
  137. }
  138. static const OSSL_PARAM known_settable_ctx_params[] = {
  139. OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
  140. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0),
  141. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0),
  142. OSSL_PARAM_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0),
  143. OSSL_PARAM_END
  144. };
  145. static const OSSL_PARAM *blake2_mac_settable_ctx_params(
  146. ossl_unused void *ctx, ossl_unused void *p_ctx)
  147. {
  148. return known_settable_ctx_params;
  149. }
  150. /*
  151. * ALL parameters should be set before init().
  152. */
  153. static int blake2_mac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[])
  154. {
  155. struct blake2_mac_data_st *macctx = vmacctx;
  156. const OSSL_PARAM *p;
  157. if (params == NULL)
  158. return 1;
  159. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SIZE)) != NULL) {
  160. size_t size;
  161. if (!OSSL_PARAM_get_size_t(p, &size)
  162. || size < 1
  163. || size > BLAKE2_OUTBYTES) {
  164. ERR_raise(ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH);
  165. return 0;
  166. }
  167. BLAKE2_PARAM_SET_DIGEST_LENGTH(&macctx->params, (uint8_t)size);
  168. }
  169. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL
  170. && !blake2_setkey(macctx, p->data, p->data_size))
  171. return 0;
  172. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CUSTOM))
  173. != NULL) {
  174. /*
  175. * The OSSL_PARAM API doesn't provide direct pointer use, so we
  176. * must handle the OSSL_PARAM structure ourselves here
  177. */
  178. if (p->data_size > BLAKE2_PERSONALBYTES) {
  179. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH);
  180. return 0;
  181. }
  182. BLAKE2_PARAM_SET_PERSONAL(&macctx->params, p->data, p->data_size);
  183. }
  184. if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_SALT)) != NULL) {
  185. /*
  186. * The OSSL_PARAM API doesn't provide direct pointer use, so we
  187. * must handle the OSSL_PARAM structure ourselves here as well
  188. */
  189. if (p->data_size > BLAKE2_SALTBYTES) {
  190. ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
  191. return 0;
  192. }
  193. BLAKE2_PARAM_SET_SALT(&macctx->params, p->data, p->data_size);
  194. }
  195. return 1;
  196. }
  197. const OSSL_DISPATCH BLAKE2_FUNCTIONS[] = {
  198. { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))blake2_mac_new },
  199. { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))blake2_mac_dup },
  200. { OSSL_FUNC_MAC_FREECTX, (void (*)(void))blake2_mac_free },
  201. { OSSL_FUNC_MAC_INIT, (void (*)(void))blake2_mac_init },
  202. { OSSL_FUNC_MAC_UPDATE, (void (*)(void))blake2_mac_update },
  203. { OSSL_FUNC_MAC_FINAL, (void (*)(void))blake2_mac_final },
  204. { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
  205. (void (*)(void))blake2_gettable_ctx_params },
  206. { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))blake2_get_ctx_params },
  207. { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
  208. (void (*)(void))blake2_mac_settable_ctx_params },
  209. { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))blake2_mac_set_ctx_params },
  210. { 0, NULL }
  211. };