]>
Commit | Line | Data |
---|---|---|
c13d2ab4 RL |
1 | =pod |
2 | ||
3 | =head1 NAME | |
4 | ||
2fd3392c | 5 | evp_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 | ||
44 | evp_generic_fetch() calls ossl_method_construct() with the given | |
f7c16d48 | 45 | I<libctx>, I<operation_id>, I<name>, and I<properties> and uses |
c13d2ab4 | 46 | it to create an EVP method with the help of the functions |
f7c16d48 RL |
47 | I<new_method>, I<up_ref_method>, and I<free_method>. |
48 | ||
57cd10dd | 49 | evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(), |
1b0f5b62 | 50 | but takes a numeric I<name_id> instead of a name. |
9c0586d5 | 51 | I<name_id> must always be nonzero; as a matter of fact, it being zero |
f7c16d48 RL |
52 | is considered a programming error. |
53 | This is meant to be used when one method needs to fetch an associated | |
2fd3392c | 54 | method, and is typically called from inside the given function |
f7c16d48 | 55 | I<new_method>. |
c13d2ab4 | 56 | |
2fd3392c RL |
57 | evp_generic_fetch_from_prov() does the same thing as evp_generic_fetch(), |
58 | but limits the search of methods to the provider given with I<prov>. | |
59 | This is meant to be used when one method needs to fetch an associated | |
60 | method in the same provider. | |
61 | ||
f7c16d48 RL |
62 | The three functions I<new_method>, I<up_ref_method>, and |
63 | I<free_method> are supposed to: | |
c13d2ab4 RL |
64 | |
65 | =over 4 | |
66 | ||
67 | =item new_method() | |
68 | ||
69 | creates an internal method from function pointers found in the | |
f7c16d48 RL |
70 | dispatch table I<fns>, with name identity I<name_id>. |
71 | The provider I<prov> and I<method_data> are also passed to be used as | |
72 | new_method() sees fit. | |
c13d2ab4 | 73 | |
7c95390e | 74 | =item up_ref_method() |
c13d2ab4 RL |
75 | |
76 | increments the reference counter for the given method, if there is | |
77 | one. | |
78 | ||
79 | =item free_method() | |
80 | ||
81 | frees the given method. | |
82 | ||
83 | =back | |
84 | ||
85 | =head1 RETURN VALUES | |
86 | ||
dfabee82 | 87 | evp_generic_fetch() returns a method on success, or NULL on error. |
c13d2ab4 RL |
88 | |
89 | =head1 EXAMPLES | |
90 | ||
91 | This is a short example of the fictitious EVP API and operation called | |
f7c16d48 | 92 | B<EVP_FOO>. |
c13d2ab4 RL |
93 | |
94 | To begin with, let's assume something like this in | |
23c48d94 | 95 | F<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 | |
113 | And 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 | ||
217 | And 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 | 270 | L<ossl_method_construct(3)> |
c13d2ab4 RL |
271 | |
272 | =head1 HISTORY | |
273 | ||
274 | The functions described here were all added in OpenSSL 3.0. | |
275 | ||
276 | =head1 COPYRIGHT | |
277 | ||
3c2bdd7d | 278 | Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
c13d2ab4 RL |
279 | |
280 | Licensed under the Apache License 2.0 (the "License"). You may not use | |
281 | this file except in compliance with the License. You can obtain a copy | |
282 | in the file LICENSE in the source distribution or at | |
283 | L<https://www.openssl.org/source/license.html>. | |
284 | ||
285 | =cut |