]> git.ipfire.org Git - thirdparty/openssl.git/blame - doc/internal/man3/evp_generic_fetch.pod
ossl_provider_upref to ossl_provider_up_ref
[thirdparty/openssl.git] / doc / internal / man3 / evp_generic_fetch.pod
CommitLineData
c13d2ab4
RL
1=pod
2
3=head1 NAME
4
5evp_generic_fetch - generic algorithm fetcher and method creator for EVP
6
7=head1 SYNOPSIS
8
9 /* Only for EVP source */
10 #include "evp_locl.h"
11
12 void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
2e49c054 13 const char *name, const char *properties,
0211740f 14 void *(*new_method)(const OSSL_DISPATCH *fns,
c13d2ab4 15 OSSL_PROVIDER *prov),
7c95390e 16 int (*up_ref_method)(void *),
0211740f 17 void (*free_method)(void *));
c13d2ab4
RL
18
19=head1 DESCRIPTION
20
21evp_generic_fetch() calls ossl_method_construct() with the given
2e49c054 22C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
c13d2ab4 23it to create an EVP method with the help of the functions
7c95390e 24C<new_method>, C<up_ref_method>, and C<free_method>.
c13d2ab4
RL
25
26The three functions are supposed to:
27
28=over 4
29
30=item new_method()
31
32creates an internal method from function pointers found in the
33dispatch table C<fns>.
34
7c95390e 35=item up_ref_method()
c13d2ab4
RL
36
37increments the reference counter for the given method, if there is
38one.
39
40=item free_method()
41
42frees the given method.
43
44=back
45
46=head1 RETURN VALUES
47
48evp_generic_fetch() returns a method on success, or B<NULL> on error.
49
50=head1 EXAMPLES
51
52This is a short example of the fictitious EVP API and operation called
53C<EVP_FOO>.
54
55To begin with, let's assume something like this in
56C<include/openssl/core_numbers.h>:
57
58 #define OSSL_OP_FOO 100
59
60 #define OSSL_OP_FOO_NEWCTX_FUNC 2001
61 #define OSSL_OP_FOO_INIT 2002
62 #define OSSL_OP_FOO_OPERATE 2003
63 #define OSSL_OP_FOO_CLEANCTX_FUNC 2004
64 #define OSSL_OP_FOO_FREECTX_FUNC 2005
65 OSSL_CORE_MAKE_FUNC(void *,OP_foo_newctx,(void))
66 OSSL_CORE_MAKE_FUNC(int,OP_foo_init,(void *vctx))
67 OSSL_CORE_MAKE_FUNC(int,OP_foo_operate,(void *vctx,
68 unsigned char *out, size_t *out_l,
69 unsigned char *in, size_t in_l))
70 OSSL_CORE_MAKE_FUNC(void,OP_foo_cleanctx,(void *vctx))
71 OSSL_CORE_MAKE_FUNC(void,OP_foo_freectx,(void *vctx))
72
73And here's the implementation of the FOO method fetcher:
74
75 /* typedef struct evp_foo_st EVP_FOO */
76 struct evp_foo_st {
77 OSSL_PROVIDER *prov;
c13d2ab4
RL
78 CRYPTO_REF_COUNT refcnt;
79 OSSL_OP_foo_newctx_fn *newctx;
80 OSSL_OP_foo_init_fn *init;
81 OSSL_OP_foo_operate_fn *operate;
82 OSSL_OP_foo_cleanctx_fn *cleanctx;
83 OSSL_OP_foo_freectx_fn *freectx;
84 };
85
86 /*
87 * In this example, we have a public method creator and destructor.
88 * It's not absolutely necessary, but is in the spirit of OpenSSL.
89 */
0211740f 90 EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
c13d2ab4
RL
91 OSSL_PROVIDER *prov)
92 {
93 EVP_FOO *foo = NULL;
94
95 if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
96 return NULL;
97
98 for (; fns->function_id != 0; fns++) {
99 switch (fns->function_id) {
100 case OSSL_OP_FOO_NEWCTX_FUNC:
101 foo->newctx = OSSL_get_OP_foo_newctx(fns);
102 break;
103 case OSSL_OP_FOO_INIT:
104 foo->init = OSSL_get_OP_foo_init(fns);
105 break;
106 case OSSL_OP_FOO_OPERATE:
107 foo->operate = OSSL_get_OP_foo_operate(fns);
108 break;
109 case OSSL_OP_FOO_CLEANCTX_FUNC:
110 foo->cleanctx = OSSL_get_OP_foo_cleanctx(fns);
111 break;
112 case OSSL_OP_FOO_FREECTX_FUNC:
113 foo->freectx = OSSL_get_OP_foo_freectx(fns);
114 break;
115 }
116 }
c13d2ab4
RL
117 foo->prov = prov;
118 if (prov)
7c95390e 119 ossl_provider_up_ref(prov);
c13d2ab4
RL
120
121 return foo;
122 }
123
124 EVP_FOO_meth_free(EVP_FOO *foo)
125 {
126 if (foo != NULL) {
127 OSSL_PROVIDER *prov = foo->prov;
128
129 OPENSSL_free(foo);
130 ossl_provider_free(prov);
131 }
132 }
133
0211740f 134 static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
c13d2ab4
RL
135 OSSL_PROVIDER *prov)
136 {
0211740f 137 return EVP_FOO_meth_from_dispatch(fns, prov);
c13d2ab4
RL
138 }
139
7c95390e 140 static int foo_up_ref(void *vfoo)
c13d2ab4
RL
141 {
142 EVP_FOO *foo = vfoo;
143 int ref = 0;
144
145 CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock);
146 return 1;
147 }
148
149 static void foo_free(void *vfoo)
150 {
151 EVP_FOO_meth_free(vfoo);
152 }
153
154 EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
2e49c054 155 const char *name,
c13d2ab4
RL
156 const char *properties)
157 {
0211740f
RL
158 EVP_FOO *foo =
159 evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
7c95390e 160 foo_from_dispatch, foo_up_ref, foo_free);
0211740f
RL
161
162 /*
163 * If this method exists in legacy form, with a constant NID for the
164 * given |name|, this is the spot to find that NID and set it in
165 * the newly constructed EVP_FOO instance.
166 */
167
168 return foo;
169
c13d2ab4
RL
170 }
171
172And finally, the library functions:
173
174 /* typedef struct evp_foo_st EVP_FOO_CTX */
175 struct evp_foo_ctx_st {
176 const EVP_FOO *foo;
177 void *provctx; /* corresponding provider context */
178 };
179
180 int EVP_FOO_CTX_reset(EVP_FOO_CTX *c)
181 {
182 if (c == NULL)
183 return 1;
184 if (c->foo != NULL && c->foo->cleanctx != NULL)
185 c->foo->cleanctx(c->provctx);
186 return 1;
187 }
188
189 EVP_FOO_CTX *EVP_FOO_CTX_new(void)
190 {
191 return OPENSSL_zalloc(sizeof(EVP_FOO_CTX));
192 }
193
194 void EVP_FOO_CTX_free(EVP_FOO_CTX *c)
195 {
196 EVP_FOO_CTX_reset(c);
197 c->foo->freectx(c->provctx);
198 OPENSSL_free(c);
199 }
200
201 int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo)
202 {
203 int ok = 1;
204
205 c->foo = foo;
206 if (c->provctx == NULL)
207 c->provctx = c->foo->newctx();
208
209 ok = c->foo->init(c->provctx);
210
211 return ok;
212 }
213
214 int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl,
215 const unsigned char *in, size_t inl)
216 {
217 int ok = 1;
218
219 ok = c->foo->update(c->provctx, out, inl, &outl, in, inl);
220 return ok;
221 }
222
223=head1 SEE ALSO
224
225L<ossl_method_construct>
226
227=head1 HISTORY
228
229The functions described here were all added in OpenSSL 3.0.
230
231=head1 COPYRIGHT
232
233Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
234
235Licensed under the Apache License 2.0 (the "License"). You may not use
236this file except in compliance with the License. You can obtain a copy
237in the file LICENSE in the source distribution or at
238L<https://www.openssl.org/source/license.html>.
239
240=cut