]> git.ipfire.org Git - thirdparty/openssl.git/blame_incremental - doc/internal/man3/evp_generic_fetch.pod
CMS KEMRecipientInfo support requires HKDF with fixed digests
[thirdparty/openssl.git] / doc / internal / man3 / evp_generic_fetch.pod
... / ...
CommitLineData
1=pod
2
3=head1 NAME
4
5evp_generic_fetch, evp_generic_fetch_from_prov
6- generic algorithm fetchers and method creators for EVP
7
8=head1 SYNOPSIS
9
10 /* Only for EVP source */
11 #include "evp_local.h"
12
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,
17 OSSL_PROVIDER *prov,
18 void *method_data),
19 void *method_data,
20 int (*up_ref_method)(void *),
21 void (*free_method)(void *));
22
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,
27 OSSL_PROVIDER *prov,
28 void *method_data),
29 void *method_data,
30 int (*up_ref_method)(void *),
31 void (*free_method)(void *));
32
33=head1 DESCRIPTION
34
35evp_generic_fetch() calls ossl_method_construct() with the given
36I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
37it to create an EVP method with the help of the functions
38I<new_method>, I<up_ref_method>, and I<free_method>.
39
40evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(),
41but limits the search of methods to the provider given with I<prov>.
42This is meant to be used when one method needs to fetch an associated
43method in the same provider.
44
45The three functions I<new_method>, I<up_ref_method>, and
46I<free_method> are supposed to:
47
48=over 4
49
50=item new_method()
51
52creates an internal method from function pointers found in the
53dispatch table I<fns>, with name identity I<name_id>.
54The provider I<prov> and I<method_data> are also passed to be used as
55new_method() sees fit.
56
57=item up_ref_method()
58
59increments the reference counter for the given method, if there is
60one.
61
62=item free_method()
63
64frees the given method.
65
66=back
67
68=head1 RETURN VALUES
69
70evp_generic_fetch() returns a method on success, or NULL on error.
71
72=head1 EXAMPLES
73
74This is a short example of the fictitious EVP API and operation called
75B<EVP_FOO>.
76
77To begin with, let's assume something like this in
78F<include/openssl/core_dispatch.h>:
79
80 #define OSSL_OP_FOO 100
81
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
87
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))
95
96And here's the implementation of the FOO method fetcher:
97
98 /* typedef struct evp_foo_st EVP_FOO */
99 struct evp_foo_st {
100 OSSL_PROVIDER *prov;
101 int name_id;
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;
108 };
109
110 /*
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.
113 */
114 EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
115 const OSSL_DISPATCH *fns,
116 OSSL_PROVIDER *prov,
117 void *data)
118 {
119 EVP_FOO *foo = NULL;
120
121 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
122 return NULL;
123
124 if (!CRYPTO_NEW_REF(&foo->refcnt, 1))
125 goto err;
126
127 foo->name_id = name_id;
128
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);
133 break;
134 case OSSL_FUNC_FOO_INIT:
135 foo->init = OSSL_FUNC_foo_init(fns);
136 break;
137 case OSSL_FUNC_FOO_OPERATE:
138 foo->operate = OSSL_FUNC_foo_operate(fns);
139 break;
140 case OSSL_FUNC_FOO_CLEANCTX:
141 foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
142 break;
143 case OSSL_FUNC_FOO_FREECTX:
144 foo->freectx = OSSL_FUNC_foo_freectx(fns);
145 break;
146 }
147 }
148 if (prov != NULL && !ossl_provider_up_ref(prov))
149 goto err;
150
151 foo->prov = prov;
152
153 return foo;
154
155 err:
156 if (foo != NULL)
157 CRYPTO_FREE_REF(&foo->refcnt);
158 OPENSSL_free(foo);
159 return NULL
160 }
161
162 EVP_FOO_meth_free(EVP_FOO *foo)
163 {
164 int i;
165
166 if (foo != NULL) {
167 OSSL_PROVIDER *prov = foo->prov;
168
169 CRYPTO_DOWN_REF(&foo->refcnt, &i);
170 if (i > 0)
171 return;
172
173 CRYPTO_FREE_REF(&foo->refcnt);
174 OPENSSL_free(foo);
175 ossl_provider_free(prov);
176 }
177 }
178
179 static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
180 OSSL_PROVIDER *prov)
181 {
182 return EVP_FOO_meth_from_algorithm(fns, prov);
183 }
184
185 static int foo_up_ref(void *vfoo)
186 {
187 EVP_FOO *foo = vfoo;
188 int ref = 0;
189
190 CRYPTO_UP_REF(&foo->refcnt, &ref);
191 return 1;
192 }
193
194 static void foo_free(void *vfoo)
195 {
196 EVP_FOO_meth_free(vfoo);
197 }
198
199 EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
200 const char *name,
201 const char *properties)
202 {
203 EVP_FOO *foo =
204 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
205 foo_from_algorithm, foo_up_ref, foo_free);
206
207 /*
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.
211 */
212
213 return foo;
214
215 }
216
217And finally, the library functions:
218
219 /* typedef struct evp_foo_st EVP_FOO_CTX */
220 struct evp_foo_ctx_st {
221 const EVP_FOO *foo;
222 void *provctx; /* corresponding provider context */
223 };
224
225 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
226 {
227 if (c == NULL)
228 return 1;
229 if (c->foo != NULL && c->foo->cleanctx != NULL)
230 c->foo->cleanctx(c->provctx);
231 return 1;
232 }
233
234 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
235 {
236 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
237 }
238
239 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
240 {
241 EVP_FOO_CTX_reset(c);
242 c->foo->freectx(c->provctx);
243 OPENSSL_free(c);
244 }
245
246 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
247 {
248 int ok = 1;
249
250 c->foo = foo;
251 if (c->provctx == NULL)
252 c->provctx = c->foo->newctx();
253
254 ok = c->foo->init(c->provctx);
255
256 return ok;
257 }
258
259 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
260 const unsigned char *in, size_t inl)
261 {
262 int ok = 1;
263
264 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
265 return ok;
266 }
267
268=head1 SEE ALSO
269
270L<ossl_method_construct(3)>
271
272=head1 HISTORY
273
274The functions described here were all added in OpenSSL 3.0.
275
276=head1 COPYRIGHT
277
278Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
279
280Licensed under the Apache License 2.0 (the "License"). You may not use
281this file except in compliance with the License. You can obtain a copy
282in the file LICENSE in the source distribution or at
283L<https://www.openssl.org/source/license.html>.
284
285=cut