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