kdf_meth.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright 2019-2023 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/evp.h>
  10. #include <openssl/err.h>
  11. #include <openssl/core.h>
  12. #include <openssl/core_dispatch.h>
  13. #include <openssl/kdf.h>
  14. #include "internal/provider.h"
  15. #include "internal/core.h"
  16. #include "crypto/evp.h"
  17. #include "evp_local.h"
  18. static int evp_kdf_up_ref(void *vkdf)
  19. {
  20. EVP_KDF *kdf = (EVP_KDF *)vkdf;
  21. int ref = 0;
  22. CRYPTO_UP_REF(&kdf->refcnt, &ref);
  23. return 1;
  24. }
  25. static void evp_kdf_free(void *vkdf)
  26. {
  27. EVP_KDF *kdf = (EVP_KDF *)vkdf;
  28. int ref = 0;
  29. if (kdf == NULL)
  30. return;
  31. CRYPTO_DOWN_REF(&kdf->refcnt, &ref);
  32. if (ref > 0)
  33. return;
  34. OPENSSL_free(kdf->type_name);
  35. ossl_provider_free(kdf->prov);
  36. CRYPTO_FREE_REF(&kdf->refcnt);
  37. OPENSSL_free(kdf);
  38. }
  39. static void *evp_kdf_new(void)
  40. {
  41. EVP_KDF *kdf = NULL;
  42. if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL
  43. || !CRYPTO_NEW_REF(&kdf->refcnt, 1)) {
  44. OPENSSL_free(kdf);
  45. return NULL;
  46. }
  47. return kdf;
  48. }
  49. static void *evp_kdf_from_algorithm(int name_id,
  50. const OSSL_ALGORITHM *algodef,
  51. OSSL_PROVIDER *prov)
  52. {
  53. const OSSL_DISPATCH *fns = algodef->implementation;
  54. EVP_KDF *kdf = NULL;
  55. int fnkdfcnt = 0, fnctxcnt = 0;
  56. if ((kdf = evp_kdf_new()) == NULL) {
  57. ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
  58. return NULL;
  59. }
  60. kdf->name_id = name_id;
  61. if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
  62. evp_kdf_free(kdf);
  63. return NULL;
  64. }
  65. kdf->description = algodef->algorithm_description;
  66. for (; fns->function_id != 0; fns++) {
  67. switch (fns->function_id) {
  68. case OSSL_FUNC_KDF_NEWCTX:
  69. if (kdf->newctx != NULL)
  70. break;
  71. kdf->newctx = OSSL_FUNC_kdf_newctx(fns);
  72. fnctxcnt++;
  73. break;
  74. case OSSL_FUNC_KDF_DUPCTX:
  75. if (kdf->dupctx != NULL)
  76. break;
  77. kdf->dupctx = OSSL_FUNC_kdf_dupctx(fns);
  78. break;
  79. case OSSL_FUNC_KDF_FREECTX:
  80. if (kdf->freectx != NULL)
  81. break;
  82. kdf->freectx = OSSL_FUNC_kdf_freectx(fns);
  83. fnctxcnt++;
  84. break;
  85. case OSSL_FUNC_KDF_RESET:
  86. if (kdf->reset != NULL)
  87. break;
  88. kdf->reset = OSSL_FUNC_kdf_reset(fns);
  89. break;
  90. case OSSL_FUNC_KDF_DERIVE:
  91. if (kdf->derive != NULL)
  92. break;
  93. kdf->derive = OSSL_FUNC_kdf_derive(fns);
  94. fnkdfcnt++;
  95. break;
  96. case OSSL_FUNC_KDF_GETTABLE_PARAMS:
  97. if (kdf->gettable_params != NULL)
  98. break;
  99. kdf->gettable_params =
  100. OSSL_FUNC_kdf_gettable_params(fns);
  101. break;
  102. case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS:
  103. if (kdf->gettable_ctx_params != NULL)
  104. break;
  105. kdf->gettable_ctx_params =
  106. OSSL_FUNC_kdf_gettable_ctx_params(fns);
  107. break;
  108. case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS:
  109. if (kdf->settable_ctx_params != NULL)
  110. break;
  111. kdf->settable_ctx_params =
  112. OSSL_FUNC_kdf_settable_ctx_params(fns);
  113. break;
  114. case OSSL_FUNC_KDF_GET_PARAMS:
  115. if (kdf->get_params != NULL)
  116. break;
  117. kdf->get_params = OSSL_FUNC_kdf_get_params(fns);
  118. break;
  119. case OSSL_FUNC_KDF_GET_CTX_PARAMS:
  120. if (kdf->get_ctx_params != NULL)
  121. break;
  122. kdf->get_ctx_params = OSSL_FUNC_kdf_get_ctx_params(fns);
  123. break;
  124. case OSSL_FUNC_KDF_SET_CTX_PARAMS:
  125. if (kdf->set_ctx_params != NULL)
  126. break;
  127. kdf->set_ctx_params = OSSL_FUNC_kdf_set_ctx_params(fns);
  128. break;
  129. }
  130. }
  131. if (fnkdfcnt != 1 || fnctxcnt != 2) {
  132. /*
  133. * In order to be a consistent set of functions we must have at least
  134. * a derive function, and a complete set of context management
  135. * functions.
  136. */
  137. evp_kdf_free(kdf);
  138. ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
  139. return NULL;
  140. }
  141. kdf->prov = prov;
  142. if (prov != NULL)
  143. ossl_provider_up_ref(prov);
  144. return kdf;
  145. }
  146. EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
  147. const char *properties)
  148. {
  149. return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties,
  150. evp_kdf_from_algorithm, evp_kdf_up_ref,
  151. evp_kdf_free);
  152. }
  153. int EVP_KDF_up_ref(EVP_KDF *kdf)
  154. {
  155. return evp_kdf_up_ref(kdf);
  156. }
  157. void EVP_KDF_free(EVP_KDF *kdf)
  158. {
  159. evp_kdf_free(kdf);
  160. }
  161. const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf)
  162. {
  163. if (kdf->gettable_params == NULL)
  164. return NULL;
  165. return kdf->gettable_params(ossl_provider_ctx(EVP_KDF_get0_provider(kdf)));
  166. }
  167. const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf)
  168. {
  169. void *alg;
  170. if (kdf->gettable_ctx_params == NULL)
  171. return NULL;
  172. alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf));
  173. return kdf->gettable_ctx_params(NULL, alg);
  174. }
  175. const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf)
  176. {
  177. void *alg;
  178. if (kdf->settable_ctx_params == NULL)
  179. return NULL;
  180. alg = ossl_provider_ctx(EVP_KDF_get0_provider(kdf));
  181. return kdf->settable_ctx_params(NULL, alg);
  182. }
  183. const OSSL_PARAM *EVP_KDF_CTX_gettable_params(EVP_KDF_CTX *ctx)
  184. {
  185. void *alg;
  186. if (ctx->meth->gettable_ctx_params == NULL)
  187. return NULL;
  188. alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth));
  189. return ctx->meth->gettable_ctx_params(ctx->algctx, alg);
  190. }
  191. const OSSL_PARAM *EVP_KDF_CTX_settable_params(EVP_KDF_CTX *ctx)
  192. {
  193. void *alg;
  194. if (ctx->meth->settable_ctx_params == NULL)
  195. return NULL;
  196. alg = ossl_provider_ctx(EVP_KDF_get0_provider(ctx->meth));
  197. return ctx->meth->settable_ctx_params(ctx->algctx, alg);
  198. }
  199. void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx,
  200. void (*fn)(EVP_KDF *kdf, void *arg),
  201. void *arg)
  202. {
  203. evp_generic_do_all(libctx, OSSL_OP_KDF,
  204. (void (*)(void *, void *))fn, arg,
  205. evp_kdf_from_algorithm, evp_kdf_up_ref, evp_kdf_free);
  206. }