]> git.ipfire.org Git - thirdparty/openssl.git/blame - doc/internal/man3/evp_generic_fetch.pod
threads_pthread.c: change inline to ossl_inline
[thirdparty/openssl.git] / doc / internal / man3 / evp_generic_fetch.pod
CommitLineData
c13d2ab4
RL
1=pod
2
3=head1 NAME
4
16ff70a5 5evp_generic_fetch, evp_generic_fetch_from_prov
f7c16d48 6- generic algorithm fetchers and method creators for EVP
c13d2ab4
RL
7
8=head1 SYNOPSIS
9
10 /* Only for EVP source */
706457b7 11 #include "evp_local.h"
c13d2ab4 12
b4250010 13 void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id,
2e49c054 14 const char *name, const char *properties,
f7c16d48 15 void *(*new_method)(int name_id,
3ca9d210
RL
16 const OSSL_DISPATCH *fns,
17 OSSL_PROVIDER *prov,
18 void *method_data),
19 void *method_data,
7c95390e 20 int (*up_ref_method)(void *),
0211740f 21 void (*free_method)(void *));
c13d2ab4 22
2fd3392c
RL
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 *));
f7c16d48 32
c13d2ab4
RL
33=head1 DESCRIPTION
34
35evp_generic_fetch() calls ossl_method_construct() with the given
f7c16d48 36I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
c13d2ab4 37it to create an EVP method with the help of the functions
f7c16d48
RL
38I<new_method>, I<up_ref_method>, and I<free_method>.
39
2fd3392c
RL
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
f7c16d48
RL
45The three functions I<new_method>, I<up_ref_method>, and
46I<free_method> are supposed to:
c13d2ab4
RL
47
48=over 4
49
50=item new_method()
51
52creates an internal method from function pointers found in the
f7c16d48
RL
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.
c13d2ab4 56
7c95390e 57=item up_ref_method()
c13d2ab4
RL
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
dfabee82 70evp_generic_fetch() returns a method on success, or NULL on error.
c13d2ab4
RL
71
72=head1 EXAMPLES
73
74This is a short example of the fictitious EVP API and operation called
f7c16d48 75B<EVP_FOO>.
c13d2ab4
RL
76
77To begin with, let's assume something like this in
23c48d94 78F<include/openssl/core_dispatch.h>:
c13d2ab4 79
363b1e5d
DMSP
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))
c13d2ab4
RL
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;
f7c16d48 101 int name_id;
c13d2ab4 102 CRYPTO_REF_COUNT refcnt;
363b1e5d
DMSP
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;
c13d2ab4
RL
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 */
309a78aa
RL
114 EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
115 const OSSL_DISPATCH *fns,
116 OSSL_PROVIDER *prov,
117 void *data)
c13d2ab4
RL
118 {
119 EVP_FOO *foo = NULL;
120
121 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
122 return NULL;
123
52c362b3
P
124 if (!CRYPTO_NEW_REF(&foo->refcnt, 1)) {
125 OPENSSL_free(foo);
126 return NULL;
127 }
128
f7c16d48
RL
129 foo->name_id = name_id;
130
c13d2ab4
RL
131 for (; fns->function_id != 0; fns++) {
132 switch (fns->function_id) {
363b1e5d
DMSP
133 case OSSL_FUNC_FOO_NEWCTX:
134 foo->newctx = OSSL_FUNC_foo_newctx(fns);
c13d2ab4 135 break;
363b1e5d
DMSP
136 case OSSL_FUNC_FOO_INIT:
137 foo->init = OSSL_FUNC_foo_init(fns);
c13d2ab4 138 break;
363b1e5d
DMSP
139 case OSSL_FUNC_FOO_OPERATE:
140 foo->operate = OSSL_FUNC_foo_operate(fns);
c13d2ab4 141 break;
363b1e5d
DMSP
142 case OSSL_FUNC_FOO_CLEANCTX:
143 foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
c13d2ab4 144 break;
363b1e5d
DMSP
145 case OSSL_FUNC_FOO_FREECTX:
146 foo->freectx = OSSL_FUNC_foo_freectx(fns);
c13d2ab4
RL
147 break;
148 }
149 }
c13d2ab4
RL
150 foo->prov = prov;
151 if (prov)
7c95390e 152 ossl_provider_up_ref(prov);
c13d2ab4
RL
153
154 return foo;
155 }
156
157 EVP_FOO_meth_free(EVP_FOO *foo)
158 {
52c362b3
P
159 int i;
160
c13d2ab4
RL
161 if (foo != NULL) {
162 OSSL_PROVIDER *prov = foo->prov;
163
52c362b3
P
164 CRYPTO_DOWN_REF(&foo->refcnt, &i);
165 if (i > 0)
166 return;
167
168 CRYPTO_FREE_REF(&foo->refcnt);
c13d2ab4
RL
169 OPENSSL_free(foo);
170 ossl_provider_free(prov);
171 }
172 }
173
309a78aa
RL
174 static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
175 OSSL_PROVIDER *prov)
c13d2ab4 176 {
309a78aa 177 return EVP_FOO_meth_from_algorithm(fns, prov);
c13d2ab4
RL
178 }
179
7c95390e 180 static int foo_up_ref(void *vfoo)
c13d2ab4
RL
181 {
182 EVP_FOO *foo = vfoo;
183 int ref = 0;
184
52c362b3 185 CRYPTO_UP_REF(&foo->refcnt, &ref);
c13d2ab4
RL
186 return 1;
187 }
188
189 static void foo_free(void *vfoo)
190 {
191 EVP_FOO_meth_free(vfoo);
192 }
193
b4250010 194 EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
2e49c054 195 const char *name,
c13d2ab4
RL
196 const char *properties)
197 {
0211740f
RL
198 EVP_FOO *foo =
199 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
309a78aa 200 foo_from_algorithm, foo_up_ref, foo_free);
0211740f
RL
201
202 /*
203 * If this method exists in legacy form, with a constant NID for the
204 * given |name|, this is the spot to find that NID and set it in
205 * the newly constructed EVP_FOO instance.
206 */
207
208 return foo;
209
c13d2ab4
RL
210 }
211
212And finally, the library functions:
213
214 /* typedef struct evp_foo_st EVP_FOO_CTX */
215 struct evp_foo_ctx_st {
216 const EVP_FOO *foo;
217 void *provctx; /* corresponding provider context */
218 };
219
220 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
221 {
222 if (c == NULL)
223 return 1;
224 if (c->foo != NULL && c->foo->cleanctx != NULL)
225 c->foo->cleanctx(c->provctx);
226 return 1;
227 }
228
229 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
230 {
231 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
232 }
233
234 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
235 {
236 EVP_FOO_CTX_reset(c);
237 c->foo->freectx(c->provctx);
238 OPENSSL_free(c);
239 }
240
241 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
242 {
243 int ok = 1;
244
245 c->foo = foo;
246 if (c->provctx == NULL)
247 c->provctx = c->foo->newctx();
248
249 ok = c->foo->init(c->provctx);
250
251 return ok;
252 }
253
254 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
255 const unsigned char *in, size_t inl)
256 {
257 int ok = 1;
258
259 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
260 return ok;
261 }
262
263=head1 SEE ALSO
264
6e4618a0 265L<ossl_method_construct(3)>
c13d2ab4
RL
266
267=head1 HISTORY
268
269The functions described here were all added in OpenSSL 3.0.
270
271=head1 COPYRIGHT
272
da1c088f 273Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
c13d2ab4
RL
274
275Licensed under the Apache License 2.0 (the "License"). You may not use
276this file except in compliance with the License. You can obtain a copy
277in the file LICENSE in the source distribution or at
278L<https://www.openssl.org/source/license.html>.
279
280=cut