]> git.ipfire.org Git - thirdparty/openssl.git/blame - doc/internal/man3/evp_generic_fetch.pod
EVP: Add the internal function evp_generic_fetch_from_prov()
[thirdparty/openssl.git] / doc / internal / man3 / evp_generic_fetch.pod
CommitLineData
c13d2ab4
RL
1=pod
2
3=head1 NAME
4
2fd3392c 5evp_generic_fetch, evp_generic_fetch_by_number, 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
b4250010 23 void *evp_generic_fetch_by_number(OSSL_LIB_CTX *ctx, int operation_id,
f7c16d48
RL
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 *));
2fd3392c
RL
32 void *evp_generic_fetch_from_prov(OSSL_PROVIDER *prov, int operation_id,
33 int name_id, const char *properties,
34 void *(*new_method)(int name_id,
35 const OSSL_DISPATCH *fns,
36 OSSL_PROVIDER *prov,
37 void *method_data),
38 void *method_data,
39 int (*up_ref_method)(void *),
40 void (*free_method)(void *));
f7c16d48 41
c13d2ab4
RL
42=head1 DESCRIPTION
43
44evp_generic_fetch() calls ossl_method_construct() with the given
f7c16d48 45I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
c13d2ab4 46it to create an EVP method with the help of the functions
f7c16d48
RL
47I<new_method>, I<up_ref_method>, and I<free_method>.
48
57cd10dd 49evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(),
1b0f5b62 50but takes a numeric I<name_id> instead of a name.
9c0586d5 51I<name_id> must always be nonzero; as a matter of fact, it being zero
f7c16d48
RL
52is considered a programming error.
53This is meant to be used when one method needs to fetch an associated
2fd3392c 54method, and is typically called from inside the given function
f7c16d48 55I<new_method>.
c13d2ab4 56
2fd3392c
RL
57evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(),
58but limits the search of methods to the provider given with I<prov>.
59This is meant to be used when one method needs to fetch an associated
60method in the same provider.
61
f7c16d48
RL
62The three functions I<new_method>, I<up_ref_method>, and
63I<free_method> are supposed to:
c13d2ab4
RL
64
65=over 4
66
67=item new_method()
68
69creates an internal method from function pointers found in the
f7c16d48
RL
70dispatch table I<fns>, with name identity I<name_id>.
71The provider I<prov> and I<method_data> are also passed to be used as
72new_method() sees fit.
c13d2ab4 73
7c95390e 74=item up_ref_method()
c13d2ab4
RL
75
76increments the reference counter for the given method, if there is
77one.
78
79=item free_method()
80
81frees the given method.
82
83=back
84
85=head1 RETURN VALUES
86
dfabee82 87evp_generic_fetch() returns a method on success, or NULL on error.
c13d2ab4
RL
88
89=head1 EXAMPLES
90
91This is a short example of the fictitious EVP API and operation called
f7c16d48 92B<EVP_FOO>.
c13d2ab4
RL
93
94To begin with, let's assume something like this in
23c48d94 95F<include/openssl/core_dispatch.h>:
c13d2ab4 96
363b1e5d
DMSP
97 #define OSSL_OP_FOO 100
98
99 #define OSSL_FUNC_FOO_NEWCTX_FUNC 2001
100 #define OSSL_FUNC_FOO_INIT 2002
101 #define OSSL_FUNC_FOO_OPERATE 2003
102 #define OSSL_FUNC_FOO_CLEANCTX_FUNC 2004
103 #define OSSL_FUNC_FOO_FREECTX_FUNC 2005
104
105 OSSL_CORE_MAKE_FUNC(void *, foo_newctx, (void))
106 OSSL_CORE_MAKE_FUNC(int, foo_init, (void *vctx))
107 OSSL_CORE_MAKE_FUNC(int, foo_operate, (void *vctx,
108 unsigned char *out, size_t *out_l,
109 unsigned char *in, size_t in_l))
110 OSSL_CORE_MAKE_FUNC(void, foo_cleanctx, (void *vctx))
111 OSSL_CORE_MAKE_FUNC(void, foo_freectx, (void *vctx))
c13d2ab4
RL
112
113And here's the implementation of the FOO method fetcher:
114
115 /* typedef struct evp_foo_st EVP_FOO */
116 struct evp_foo_st {
117 OSSL_PROVIDER *prov;
f7c16d48 118 int name_id;
c13d2ab4 119 CRYPTO_REF_COUNT refcnt;
363b1e5d
DMSP
120 OSSL_FUNC_foo_newctx_fn *newctx;
121 OSSL_FUNC_foo_init_fn *init;
122 OSSL_FUNC_foo_operate_fn *operate;
123 OSSL_FUNC_foo_cleanctx_fn *cleanctx;
124 OSSL_FUNC_foo_freectx_fn *freectx;
c13d2ab4
RL
125 };
126
127 /*
128 * In this example, we have a public method creator and destructor.
129 * It's not absolutely necessary, but is in the spirit of OpenSSL.
130 */
309a78aa
RL
131 EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
132 const OSSL_DISPATCH *fns,
133 OSSL_PROVIDER *prov,
134 void *data)
c13d2ab4
RL
135 {
136 EVP_FOO *foo = NULL;
137
138 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
139 return NULL;
140
f7c16d48
RL
141 foo->name_id = name_id;
142
c13d2ab4
RL
143 for (; fns->function_id != 0; fns++) {
144 switch (fns->function_id) {
363b1e5d
DMSP
145 case OSSL_FUNC_FOO_NEWCTX:
146 foo->newctx = OSSL_FUNC_foo_newctx(fns);
c13d2ab4 147 break;
363b1e5d
DMSP
148 case OSSL_FUNC_FOO_INIT:
149 foo->init = OSSL_FUNC_foo_init(fns);
c13d2ab4 150 break;
363b1e5d
DMSP
151 case OSSL_FUNC_FOO_OPERATE:
152 foo->operate = OSSL_FUNC_foo_operate(fns);
c13d2ab4 153 break;
363b1e5d
DMSP
154 case OSSL_FUNC_FOO_CLEANCTX:
155 foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
c13d2ab4 156 break;
363b1e5d
DMSP
157 case OSSL_FUNC_FOO_FREECTX:
158 foo->freectx = OSSL_FUNC_foo_freectx(fns);
c13d2ab4
RL
159 break;
160 }
161 }
c13d2ab4
RL
162 foo->prov = prov;
163 if (prov)
7c95390e 164 ossl_provider_up_ref(prov);
c13d2ab4
RL
165
166 return foo;
167 }
168
169 EVP_FOO_meth_free(EVP_FOO *foo)
170 {
171 if (foo != NULL) {
172 OSSL_PROVIDER *prov = foo->prov;
173
174 OPENSSL_free(foo);
175 ossl_provider_free(prov);
176 }
177 }
178
309a78aa
RL
179 static void *foo_from_algorithm(const OSSL_DISPATCH *fns,
180 OSSL_PROVIDER *prov)
c13d2ab4 181 {
309a78aa 182 return EVP_FOO_meth_from_algorithm(fns, prov);
c13d2ab4
RL
183 }
184
7c95390e 185 static int foo_up_ref(void *vfoo)
c13d2ab4
RL
186 {
187 EVP_FOO *foo = vfoo;
188 int ref = 0;
189
190 CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock);
191 return 1;
192 }
193
194 static void foo_free(void *vfoo)
195 {
196 EVP_FOO_meth_free(vfoo);
197 }
198
b4250010 199 EVP_FOO *EVP_FOO_fetch(OSSL_LIB_CTX *ctx,
2e49c054 200 const char *name,
c13d2ab4
RL
201 const char *properties)
202 {
0211740f
RL
203 EVP_FOO *foo =
204 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
309a78aa 205 foo_from_algorithm, foo_up_ref, foo_free);
0211740f
RL
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
c13d2ab4
RL
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
6e4618a0 270L<ossl_method_construct(3)>
c13d2ab4
RL
271
272=head1 HISTORY
273
274The functions described here were all added in OpenSSL 3.0.
275
276=head1 COPYRIGHT
277
3c2bdd7d 278Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
c13d2ab4
RL
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