5 evp_generic_fetch, evp_generic_fetch_from_prov
6 - generic algorithm fetchers and method creators for EVP
10 /* Only for EVP source */
11 #include "evp_local.h"
13 void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
14 const char *name, const char *properties,
15 void *(*new_method)(int name_id,
16 const OSSL_DISPATCH *fns,
20 int (*up_ref_method)(void *),
21 void (*free_method)(void *));
23 void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
24 int name_id, const char *properties,
25 void *(*new_method)(int name_id,
26 const OSSL_DISPATCH *fns,
30 int (*up_ref_method)(void *),
31 void (*free_method)(void *));
35 evp_generic_fetch() calls ossl_method_construct() with the given
36 I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
37 it to create an EVP method with the help of the functions
38 I<new_method>, I<up_ref_method>, and I<free_method>.
40 evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(),
41 but limits the search of methods to the provider given with I<prov>.
42 This is meant to be used when one method needs to fetch an associated
43 method in the same provider.
45 The three functions I<new_method>, I<up_ref_method>, and
46 I<free_method> are supposed to:
52 creates an internal method from function pointers found in the
53 dispatch table I<fns>, with name identity I<name_id>.
54 The provider I<prov> and I<method_data> are also passed to be used as
55 new_method() sees fit.
59 increments the reference counter for the given method, if there is
64 frees the given method.
70 evp_generic_fetch() returns a method on success, or NULL on error.
74 This is a short example of the fictitious EVP API and operation called
77 To begin with, let's assume something like this in
78 F<include/openssl/core_dispatch.h>:
80 #define OSSL_OP_FOO 100
82 #define OSSL_FUNC_FOO_NEWCTX_FUNC 2001
83 #define OSSL_FUNC_FOO_INIT 2002
84 #define OSSL_FUNC_FOO_OPERATE 2003
85 #define OSSL_FUNC_FOO_CLEANCTX_FUNC 2004
86 #define OSSL_FUNC_FOO_FREECTX_FUNC 2005
88 OSSL_CORE_MAKE_FUNC(void *, foo_newctx, (void))
89 OSSL_CORE_MAKE_FUNC(int, foo_init, (void *vctx))
90 OSSL_CORE_MAKE_FUNC(int, foo_operate, (void *vctx,
91 unsigned char *out, size_t *out_l,
92 unsigned char *in, size_t in_l))
93 OSSL_CORE_MAKE_FUNC(void, foo_cleanctx, (void *vctx))
94 OSSL_CORE_MAKE_FUNC(void, foo_freectx, (void *vctx))
96 And here's the implementation of the FOO method fetcher:
98 /* typedef struct evp_foo_st EVP_FOO */
102 CRYPTO_REF_COUNT refcnt;
103 OSSL_FUNC_foo_newctx_fn *newctx;
104 OSSL_FUNC_foo_init_fn *init;
105 OSSL_FUNC_foo_operate_fn *operate;
106 OSSL_FUNC_foo_cleanctx_fn *cleanctx;
107 OSSL_FUNC_foo_freectx_fn *freectx;
111 * In this example, we have a public method creator and destructor.
112 * It's not absolutely necessary, but is in the spirit of OpenSSL.
114 EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
115 const OSSL_DISPATCH *fns,
121 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
124 if (!CRYPTO_NEW_REF(&foo->refcnt, 1))
127 foo->name_id = name_id;
129 for (; fns->function_id != 0; fns++) {
130 switch (fns->function_id) {
131 case OSSL_FUNC_FOO_NEWCTX:
132 foo->newctx = OSSL_FUNC_foo_newctx(fns);
134 case OSSL_FUNC_FOO_INIT:
135 foo->init = OSSL_FUNC_foo_init(fns);
137 case OSSL_FUNC_FOO_OPERATE:
138 foo->operate = OSSL_FUNC_foo_operate(fns);
140 case OSSL_FUNC_FOO_CLEANCTX:
141 foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
143 case OSSL_FUNC_FOO_FREECTX:
144 foo->freectx = OSSL_FUNC_foo_freectx(fns);
148 if (prov != NULL && !ossl_provider_up_ref(prov))
157 CRYPTO_FREE_REF(&foo->refcnt);
162 EVP_FOO_meth_free(EVP_FOO *foo)
167 OSSL_PROVIDER *prov = foo->prov;
169 CRYPTO_DOWN_REF(&foo->refcnt, &i);
173 CRYPTO_FREE_REF(&foo->refcnt);
175 ossl_provider_free(prov);
179 static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
182 return EVP_FOO_meth_from_algorithm(fns, prov);
185 static int foo_up_ref(void *vfoo)
190 CRYPTO_UP_REF(&foo->refcnt, &ref);
194 static void foo_free(void *vfoo)
196 EVP_FOO_meth_free(vfoo);
199 EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
201 const char *properties)
204 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
205 foo_from_algorithm, foo_up_ref, foo_free);
208 * If this method exists in legacy form, with a constant NID for the
209 * given |name|, this is the spot to find that NID and set it in
210 * the newly constructed EVP_FOO instance.
217 And finally, the library functions:
219 /* typedef struct evp_foo_st EVP_FOO_CTX */
220 struct evp_foo_ctx_st {
222 void *provctx; /* corresponding provider context */
225 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
229 if (c->foo != NULL && c->foo->cleanctx != NULL)
230 c->foo->cleanctx(c->provctx);
234 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
236 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
239 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
241 EVP_FOO_CTX_reset(c);
242 c->foo->freectx(c->provctx);
246 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
251 if (c->provctx == NULL)
252 c->provctx = c->foo->newctx();
254 ok = c->foo->init(c->provctx);
259 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
260 const unsigned char *in, size_t inl)
264 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
270 L<ossl_method_construct(3)>
274 The functions described here were all added in OpenSSL 3.0.
278 Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
280 Licensed under the Apache License 2.0 (the "License"). You may not use
281 this file except in compliance with the License. You can obtain a copy
282 in the file LICENSE in the source distribution or at
283 L<https://www.openssl.org/source/license.html>.