kdf_meth.c 6.6 KB

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