5 evp_generic_fetch - generic algorithm fetcher and method creator for EVP
9 /* Only for EVP source */
12 void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
13 const char *name, const char *properties,
14 void *(*new_method)(const char *name,
15 const OSSL_DISPATCH *fns,
19 int (*up_ref_method)(void *),
20 void (*free_method)(void *));
24 evp_generic_fetch() calls ossl_method_construct() with the given
25 C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
26 it to create an EVP method with the help of the functions
27 C<new_method>, C<up_ref_method>, and C<free_method>.
29 The three functions are supposed to:
35 creates an internal method from function pointers found in the
36 dispatch table C<fns>.
37 The algorithm I<name>, provider I<prov>, and I<method_data> are
38 also passed to be used as new_method() sees fit.
42 increments the reference counter for the given method, if there is
47 frees the given method.
53 evp_generic_fetch() returns a method on success, or B<NULL> on error.
57 This is a short example of the fictitious EVP API and operation called
60 To begin with, let's assume something like this in
61 C<include/openssl/core_numbers.h>:
63 #define OSSL_OP_FOO 100
65 #define OSSL_OP_FOO_NEWCTX_FUNC 2001
66 #define OSSL_OP_FOO_INIT 2002
67 #define OSSL_OP_FOO_OPERATE 2003
68 #define OSSL_OP_FOO_CLEANCTX_FUNC 2004
69 #define OSSL_OP_FOO_FREECTX_FUNC 2005
70 OSSL_CORE_MAKE_FUNC(void *,OP_foo_newctx,(void))
71 OSSL_CORE_MAKE_FUNC(int,OP_foo_init,(void *vctx))
72 OSSL_CORE_MAKE_FUNC(int,OP_foo_operate,(void *vctx,
73 unsigned char *out, size_t *out_l,
74 unsigned char *in, size_t in_l))
75 OSSL_CORE_MAKE_FUNC(void,OP_foo_cleanctx,(void *vctx))
76 OSSL_CORE_MAKE_FUNC(void,OP_foo_freectx,(void *vctx))
78 And here's the implementation of the FOO method fetcher:
80 /* typedef struct evp_foo_st EVP_FOO */
83 CRYPTO_REF_COUNT refcnt;
84 OSSL_OP_foo_newctx_fn *newctx;
85 OSSL_OP_foo_init_fn *init;
86 OSSL_OP_foo_operate_fn *operate;
87 OSSL_OP_foo_cleanctx_fn *cleanctx;
88 OSSL_OP_foo_freectx_fn *freectx;
92 * In this example, we have a public method creator and destructor.
93 * It's not absolutely necessary, but is in the spirit of OpenSSL.
95 EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
100 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
103 for (; fns->function_id != 0; fns++) {
104 switch (fns->function_id) {
105 case OSSL_OP_FOO_NEWCTX_FUNC:
106 foo->newctx = OSSL_get_OP_foo_newctx(fns);
108 case OSSL_OP_FOO_INIT:
109 foo->init = OSSL_get_OP_foo_init(fns);
111 case OSSL_OP_FOO_OPERATE:
112 foo->operate = OSSL_get_OP_foo_operate(fns);
114 case OSSL_OP_FOO_CLEANCTX_FUNC:
115 foo->cleanctx = OSSL_get_OP_foo_cleanctx(fns);
117 case OSSL_OP_FOO_FREECTX_FUNC:
118 foo->freectx = OSSL_get_OP_foo_freectx(fns);
124 ossl_provider_up_ref(prov);
129 EVP_FOO_meth_free(EVP_FOO *foo)
132 OSSL_PROVIDER *prov = foo->prov;
135 ossl_provider_free(prov);
139 static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
142 return EVP_FOO_meth_from_dispatch(fns, prov);
145 static int foo_up_ref(void *vfoo)
150 CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock);
154 static void foo_free(void *vfoo)
156 EVP_FOO_meth_free(vfoo);
159 EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
161 const char *properties)
164 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
165 foo_from_dispatch, foo_up_ref, foo_free);
168 * If this method exists in legacy form, with a constant NID for the
169 * given |name|, this is the spot to find that NID and set it in
170 * the newly constructed EVP_FOO instance.
177 And finally, the library functions:
179 /* typedef struct evp_foo_st EVP_FOO_CTX */
180 struct evp_foo_ctx_st {
182 void *provctx; /* corresponding provider context */
185 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
189 if (c->foo != NULL && c->foo->cleanctx != NULL)
190 c->foo->cleanctx(c->provctx);
194 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
196 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
199 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
201 EVP_FOO_CTX_reset(c);
202 c->foo->freectx(c->provctx);
206 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
211 if (c->provctx == NULL)
212 c->provctx = c->foo->newctx();
214 ok = c->foo->init(c->provctx);
219 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
220 const unsigned char *in, size_t inl)
224 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
230 L<ossl_method_construct>
234 The functions described here were all added in OpenSSL 3.0.
238 Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
240 Licensed under the Apache License 2.0 (the "License"). You may not use
241 this file except in compliance with the License. You can obtain a copy
242 in the file LICENSE in the source distribution or at
243 L<https://www.openssl.org/source/license.html>.