evp_generic_fetch.pod 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. =pod
  2. =head1 NAME
  3. evp_generic_fetch, evp_generic_fetch_from_prov
  4. - generic algorithm fetchers and method creators for EVP
  5. =head1 SYNOPSIS
  6. /* Only for EVP source */
  7. #include "evp_local.h"
  8. void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
  9. const char *name, const char *properties,
  10. void *(*new_method)(int name_id,
  11. const OSSL_DISPATCH *fns,
  12. OSSL_PROVIDER *prov,
  13. void *method_data),
  14. void *method_data,
  15. int (*up_ref_method)(void *),
  16. void (*free_method)(void *));
  17. void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
  18. int name_id, const char *properties,
  19. void *(*new_method)(int name_id,
  20. const OSSL_DISPATCH *fns,
  21. OSSL_PROVIDER *prov,
  22. void *method_data),
  23. void *method_data,
  24. int (*up_ref_method)(void *),
  25. void (*free_method)(void *));
  26. =head1 DESCRIPTION
  27. evp_generic_fetch() calls ossl_method_construct() with the given
  28. I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
  29. it to create an EVP method with the help of the functions
  30. I<new_method>, I<up_ref_method>, and I<free_method>.
  31. evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(),
  32. but limits the search of methods to the provider given with I<prov>.
  33. This is meant to be used when one method needs to fetch an associated
  34. method in the same provider.
  35. The three functions I<new_method>, I<up_ref_method>, and
  36. I<free_method> are supposed to:
  37. =over 4
  38. =item new_method()
  39. creates an internal method from function pointers found in the
  40. dispatch table I<fns>, with name identity I<name_id>.
  41. The provider I<prov> and I<method_data> are also passed to be used as
  42. new_method() sees fit.
  43. =item up_ref_method()
  44. increments the reference counter for the given method, if there is
  45. one.
  46. =item free_method()
  47. frees the given method.
  48. =back
  49. =head1 RETURN VALUES
  50. evp_generic_fetch() returns a method on success, or NULL on error.
  51. =head1 EXAMPLES
  52. This is a short example of the fictitious EVP API and operation called
  53. B<EVP_FOO>.
  54. To begin with, let's assume something like this in
  55. F<include/openssl/core_dispatch.h>:
  56. #define OSSL_OP_FOO 100
  57. #define OSSL_FUNC_FOO_NEWCTX_FUNC 2001
  58. #define OSSL_FUNC_FOO_INIT 2002
  59. #define OSSL_FUNC_FOO_OPERATE 2003
  60. #define OSSL_FUNC_FOO_CLEANCTX_FUNC 2004
  61. #define OSSL_FUNC_FOO_FREECTX_FUNC 2005
  62. OSSL_CORE_MAKE_FUNC(void *, foo_newctx, (void))
  63. OSSL_CORE_MAKE_FUNC(int, foo_init, (void *vctx))
  64. OSSL_CORE_MAKE_FUNC(int, foo_operate, (void *vctx,
  65. unsigned char *out, size_t *out_l,
  66. unsigned char *in, size_t in_l))
  67. OSSL_CORE_MAKE_FUNC(void, foo_cleanctx, (void *vctx))
  68. OSSL_CORE_MAKE_FUNC(void, foo_freectx, (void *vctx))
  69. And here's the implementation of the FOO method fetcher:
  70. /* typedef struct evp_foo_st EVP_FOO */
  71. struct evp_foo_st {
  72. OSSL_PROVIDER *prov;
  73. int name_id;
  74. CRYPTO_REF_COUNT refcnt;
  75. OSSL_FUNC_foo_newctx_fn *newctx;
  76. OSSL_FUNC_foo_init_fn *init;
  77. OSSL_FUNC_foo_operate_fn *operate;
  78. OSSL_FUNC_foo_cleanctx_fn *cleanctx;
  79. OSSL_FUNC_foo_freectx_fn *freectx;
  80. };
  81. /*
  82. * In this example, we have a public method creator and destructor.
  83. * It's not absolutely necessary, but is in the spirit of OpenSSL.
  84. */
  85. EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
  86. const OSSL_DISPATCH *fns,
  87. OSSL_PROVIDER *prov,
  88. void *data)
  89. {
  90. EVP_FOO *foo = NULL;
  91. if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
  92. return NULL;
  93. if (!CRYPTO_NEW_REF(&foo->refcnt, 1)) {
  94. OPENSSL_free(foo);
  95. return NULL;
  96. }
  97. foo->name_id = name_id;
  98. for (; fns->function_id != 0; fns++) {
  99. switch (fns->function_id) {
  100. case OSSL_FUNC_FOO_NEWCTX:
  101. foo->newctx = OSSL_FUNC_foo_newctx(fns);
  102. break;
  103. case OSSL_FUNC_FOO_INIT:
  104. foo->init = OSSL_FUNC_foo_init(fns);
  105. break;
  106. case OSSL_FUNC_FOO_OPERATE:
  107. foo->operate = OSSL_FUNC_foo_operate(fns);
  108. break;
  109. case OSSL_FUNC_FOO_CLEANCTX:
  110. foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
  111. break;
  112. case OSSL_FUNC_FOO_FREECTX:
  113. foo->freectx = OSSL_FUNC_foo_freectx(fns);
  114. break;
  115. }
  116. }
  117. foo->prov = prov;
  118. if (prov)
  119. ossl_provider_up_ref(prov);
  120. return foo;
  121. }
  122. EVP_FOO_meth_free(EVP_FOO *foo)
  123. {
  124. int i;
  125. if (foo != NULL) {
  126. OSSL_PROVIDER *prov = foo->prov;
  127. CRYPTO_DOWN_REF(&foo->refcnt, &i);
  128. if (i > 0)
  129. return;
  130. CRYPTO_FREE_REF(&foo->refcnt);
  131. OPENSSL_free(foo);
  132. ossl_provider_free(prov);
  133. }
  134. }
  135. static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
  136. OSSL_PROVIDER *prov)
  137. {
  138. return EVP_FOO_meth_from_algorithm(fns, prov);
  139. }
  140. static int foo_up_ref(void *vfoo)
  141. {
  142. EVP_FOO *foo = vfoo;
  143. int ref = 0;
  144. CRYPTO_UP_REF(&foo->refcnt, &ref);
  145. return 1;
  146. }
  147. static void foo_free(void *vfoo)
  148. {
  149. EVP_FOO_meth_free(vfoo);
  150. }
  151. EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
  152. const char *name,
  153. const char *properties)
  154. {
  155. EVP_FOO *foo =
  156. evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
  157. foo_from_algorithm, foo_up_ref, foo_free);
  158. /*
  159. * If this method exists in legacy form, with a constant NID for the
  160. * given |name|, this is the spot to find that NID and set it in
  161. * the newly constructed EVP_FOO instance.
  162. */
  163. return foo;
  164. }
  165. And finally, the library functions:
  166. /* typedef struct evp_foo_st EVP_FOO_CTX */
  167. struct evp_foo_ctx_st {
  168. const EVP_FOO *foo;
  169. void *provctx; /* corresponding provider context */
  170. };
  171. int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
  172. {
  173. if (c == NULL)
  174. return 1;
  175. if (c->foo != NULL && c->foo->cleanctx != NULL)
  176. c->foo->cleanctx(c->provctx);
  177. return 1;
  178. }
  179. EVP_FOO_CTX *EVP_FOO_CTX_new(void)
  180. {
  181. return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
  182. }
  183. void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
  184. {
  185. EVP_FOO_CTX_reset(c);
  186. c->foo->freectx(c->provctx);
  187. OPENSSL_free(c);
  188. }
  189. int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
  190. {
  191. int ok = 1;
  192. c->foo = foo;
  193. if (c->provctx == NULL)
  194. c->provctx = c->foo->newctx();
  195. ok = c->foo->init(c->provctx);
  196. return ok;
  197. }
  198. int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
  199. const unsigned char *in, size_t inl)
  200. {
  201. int ok = 1;
  202. ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
  203. return ok;
  204. }
  205. =head1 SEE ALSO
  206. L<ossl_method_construct(3)>
  207. =head1 HISTORY
  208. The functions described here were all added in OpenSSL 3.0.
  209. =head1 COPYRIGHT
  210. Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
  211. Licensed under the Apache License 2.0 (the "License"). You may not use
  212. this file except in compliance with the License. You can obtain a copy
  213. in the file LICENSE in the source distribution or at
  214. L<https://www.openssl.org/source/license.html>.
  215. =cut