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 OSSL_DISPATCH *fns,
16 int (*up_ref_method)(void *),
17 void (*free_method)(void *));
21 evp_generic_fetch() calls ossl_method_construct() with the given
22 C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
23 it to create an EVP method with the help of the functions
24 C<new_method>, C<up_ref_method>, and C<free_method>.
26 The three functions are supposed to:
32 creates an internal method from function pointers found in the
33 dispatch table C<fns>.
37 increments the reference counter for the given method, if there is
42 frees the given method.
48 evp_generic_fetch() returns a method on success, or B<NULL> on error.
52 This is a short example of the fictitious EVP API and operation called
55 To begin with, let's assume something like this in
56 C<include/openssl/core_numbers.h>:
58 #define OSSL_OP_FOO 100
60 #define OSSL_OP_FOO_NEWCTX_FUNC 2001
61 #define OSSL_OP_FOO_INIT 2002
62 #define OSSL_OP_FOO_OPERATE 2003
63 #define OSSL_OP_FOO_CLEANCTX_FUNC 2004
64 #define OSSL_OP_FOO_FREECTX_FUNC 2005
65 OSSL_CORE_MAKE_FUNC(void *,OP_foo_newctx,(void))
66 OSSL_CORE_MAKE_FUNC(int,OP_foo_init,(void *vctx))
67 OSSL_CORE_MAKE_FUNC(int,OP_foo_operate,(void *vctx,
68 unsigned char *out, size_t *out_l,
69 unsigned char *in, size_t in_l))
70 OSSL_CORE_MAKE_FUNC(void,OP_foo_cleanctx,(void *vctx))
71 OSSL_CORE_MAKE_FUNC(void,OP_foo_freectx,(void *vctx))
73 And here's the implementation of the FOO method fetcher:
75 /* typedef struct evp_foo_st EVP_FOO */
78 CRYPTO_REF_COUNT refcnt;
79 OSSL_OP_foo_newctx_fn *newctx;
80 OSSL_OP_foo_init_fn *init;
81 OSSL_OP_foo_operate_fn *operate;
82 OSSL_OP_foo_cleanctx_fn *cleanctx;
83 OSSL_OP_foo_freectx_fn *freectx;
87 * In this example, we have a public method creator and destructor.
88 * It's not absolutely necessary, but is in the spirit of OpenSSL.
90 EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
95 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
98 for (; fns->function_id != 0; fns++) {
99 switch (fns->function_id) {
100 case OSSL_OP_FOO_NEWCTX_FUNC:
101 foo->newctx = OSSL_get_OP_foo_newctx(fns);
103 case OSSL_OP_FOO_INIT:
104 foo->init = OSSL_get_OP_foo_init(fns);
106 case OSSL_OP_FOO_OPERATE:
107 foo->operate = OSSL_get_OP_foo_operate(fns);
109 case OSSL_OP_FOO_CLEANCTX_FUNC:
110 foo->cleanctx = OSSL_get_OP_foo_cleanctx(fns);
112 case OSSL_OP_FOO_FREECTX_FUNC:
113 foo->freectx = OSSL_get_OP_foo_freectx(fns);
119 ossl_provider_up_ref(prov);
124 EVP_FOO_meth_free(EVP_FOO *foo)
127 OSSL_PROVIDER *prov = foo->prov;
130 ossl_provider_free(prov);
134 static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
137 return EVP_FOO_meth_from_dispatch(fns, prov);
140 static int foo_up_ref(void *vfoo)
145 CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock);
149 static void foo_free(void *vfoo)
151 EVP_FOO_meth_free(vfoo);
154 EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
156 const char *properties)
159 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
160 foo_from_dispatch, foo_up_ref, foo_free);
163 * If this method exists in legacy form, with a constant NID for the
164 * given |name|, this is the spot to find that NID and set it in
165 * the newly constructed EVP_FOO instance.
172 And finally, the library functions:
174 /* typedef struct evp_foo_st EVP_FOO_CTX */
175 struct evp_foo_ctx_st {
177 void *provctx; /* corresponding provider context */
180 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
184 if (c->foo != NULL && c->foo->cleanctx != NULL)
185 c->foo->cleanctx(c->provctx);
189 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
191 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
194 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
196 EVP_FOO_CTX_reset(c);
197 c->foo->freectx(c->provctx);
201 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
206 if (c->provctx == NULL)
207 c->provctx = c->foo->newctx();
209 ok = c->foo->init(c->provctx);
214 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
215 const unsigned char *in, size_t inl)
219 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
225 L<ossl_method_construct>
229 The functions described here were all added in OpenSSL 3.0.
233 Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
235 Licensed under the Apache License 2.0 (the "License"). You may not use
236 this file except in compliance with the License. You can obtain a copy
237 in the file LICENSE in the source distribution or at
238 L<https://www.openssl.org/source/license.html>.