1 | =pod
|
---|
2 |
|
---|
3 | =head1 NAME
|
---|
4 |
|
---|
5 | evp_generic_fetch, evp_generic_fetch_by_number, 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_by_number(OSSL_LIB_CTX *ctx, 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 | 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 *));
|
---|
41 |
|
---|
42 | =head1 DESCRIPTION
|
---|
43 |
|
---|
44 | evp_generic_fetch() calls ossl_method_construct() with the given
|
---|
45 | I<libctx>, I<operation_id>, I<name>, and I<properties> and uses
|
---|
46 | it to create an EVP method with the help of the functions
|
---|
47 | I<new_method>, I<up_ref_method>, and I<free_method>.
|
---|
48 |
|
---|
49 | evp_generic_fetch_by_number() does the same thing as evp_generic_fetch(),
|
---|
50 | but takes a numeric I<name_id> instead of a name.
|
---|
51 | I<name_id> must always be nonzero; as a matter of fact, it being zero
|
---|
52 | is considered a programming error.
|
---|
53 | This is meant to be used when one method needs to fetch an associated
|
---|
54 | method, and is typically called from inside the given function
|
---|
55 | I<new_method>.
|
---|
56 |
|
---|
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 |
|
---|
62 | The three functions I<new_method>, I<up_ref_method>, and
|
---|
63 | I<free_method> are supposed to:
|
---|
64 |
|
---|
65 | =over 4
|
---|
66 |
|
---|
67 | =item new_method()
|
---|
68 |
|
---|
69 | creates an internal method from function pointers found in the
|
---|
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.
|
---|
73 |
|
---|
74 | =item up_ref_method()
|
---|
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 |
|
---|
87 | evp_generic_fetch() returns a method on success, or NULL on error.
|
---|
88 |
|
---|
89 | =head1 EXAMPLES
|
---|
90 |
|
---|
91 | This is a short example of the fictitious EVP API and operation called
|
---|
92 | B<EVP_FOO>.
|
---|
93 |
|
---|
94 | To begin with, let's assume something like this in
|
---|
95 | F<include/openssl/core_dispatch.h>:
|
---|
96 |
|
---|
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))
|
---|
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;
|
---|
118 | int name_id;
|
---|
119 | CRYPTO_REF_COUNT refcnt;
|
---|
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;
|
---|
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 | */
|
---|
131 | EVP_FOO *EVP_FOO_meth_from_algorithm(int name_id,
|
---|
132 | const OSSL_DISPATCH *fns,
|
---|
133 | OSSL_PROVIDER *prov,
|
---|
134 | void *data)
|
---|
135 | {
|
---|
136 | EVP_FOO *foo = NULL;
|
---|
137 |
|
---|
138 | if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
|
---|
139 | return NULL;
|
---|
140 |
|
---|
141 | foo->name_id = name_id;
|
---|
142 |
|
---|
143 | for (; fns->function_id != 0; fns++) {
|
---|
144 | switch (fns->function_id) {
|
---|
145 | case OSSL_FUNC_FOO_NEWCTX:
|
---|
146 | foo->newctx = OSSL_FUNC_foo_newctx(fns);
|
---|
147 | break;
|
---|
148 | case OSSL_FUNC_FOO_INIT:
|
---|
149 | foo->init = OSSL_FUNC_foo_init(fns);
|
---|
150 | break;
|
---|
151 | case OSSL_FUNC_FOO_OPERATE:
|
---|
152 | foo->operate = OSSL_FUNC_foo_operate(fns);
|
---|
153 | break;
|
---|
154 | case OSSL_FUNC_FOO_CLEANCTX:
|
---|
155 | foo->cleanctx = OSSL_FUNC_foo_cleanctx(fns);
|
---|
156 | break;
|
---|
157 | case OSSL_FUNC_FOO_FREECTX:
|
---|
158 | foo->freectx = OSSL_FUNC_foo_freectx(fns);
|
---|
159 | break;
|
---|
160 | }
|
---|
161 | }
|
---|
162 | foo->prov = prov;
|
---|
163 | if (prov)
|
---|
164 | ossl_provider_up_ref(prov);
|
---|
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 |
|
---|
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, foo_lock);
|
---|
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 |
|
---|
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 |
|
---|
270 | L<ossl_method_construct(3)>
|
---|
271 |
|
---|
272 | =head1 HISTORY
|
---|
273 |
|
---|
274 | The functions described here were all added in OpenSSL 3.0.
|
---|
275 |
|
---|
276 | =head1 COPYRIGHT
|
---|
277 |
|
---|
278 | Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
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
|
---|