]>
Commit | Line | Data |
---|---|---|
d4c69c69 RL |
1 | =pod |
2 | ||
3 | =head1 NAME | |
4 | ||
5 | provider-base | |
6 | - The basic OpenSSL library E<lt>-E<gt> provider functions | |
7 | ||
8 | =head1 SYNOPSIS | |
9 | ||
10 | #include <openssl/core_numbers.h> | |
11 | ||
12 | /* | |
13 | * None of these are actual functions, but are displayed like this for | |
14 | * the function signatures for functions that are offered as function | |
15 | * pointers in OSSL_DISPATCH arrays. | |
16 | */ | |
17 | ||
18 | /* Functions offered by libcrypto to the providers */ | |
19 | const OSSL_ITEM *core_get_param_types(const OSSL_PROVIDER *prov); | |
20 | int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); | |
21 | int core_thread_start(const OSSL_PROVIDER *prov, | |
22 | OSSL_thread_stop_handler_fn handfn); | |
d4c69c69 | 23 | OPENSSL_CTX *core_get_library_context(const OSSL_PROVIDER *prov); |
49c64346 RL |
24 | void core_new_error(const OSSL_PROVIDER *prov); |
25 | void core_set_error_debug(const OSSL_PROVIDER *prov, | |
26 | const char *file, int line, const char *func); | |
27 | void core_vset_error(const OSSL_PROVIDER *prov, | |
28 | uint32_t reason, const char *fmt, va_list args); | |
d4c69c69 RL |
29 | |
30 | /* | |
31 | * Some OpenSSL functionality is directly offered to providers via | |
32 | * dispatch | |
33 | */ | |
34 | void *CRYPTO_malloc(size_t num, const char *file, int line); | |
35 | void *CRYPTO_zalloc(size_t num, const char *file, int line); | |
36 | void *CRYPTO_memdup(const void *str, size_t siz, | |
37 | const char *file, int line); | |
38 | char *CRYPTO_strdup(const char *str, const char *file, int line); | |
39 | char *CRYPTO_strndup(const char *str, size_t s, | |
40 | const char *file, int line); | |
41 | void CRYPTO_free(void *ptr, const char *file, int line); | |
42 | void CRYPTO_clear_free(void *ptr, size_t num, | |
43 | const char *file, int line); | |
44 | void *CRYPTO_realloc(void *addr, size_t num, | |
45 | const char *file, int line); | |
46 | void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, | |
47 | const char *file, int line); | |
48 | void *CRYPTO_secure_malloc(size_t num, const char *file, int line); | |
49 | void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); | |
50 | void CRYPTO_secure_free(void *ptr, const char *file, int line); | |
51 | void CRYPTO_secure_clear_free(void *ptr, size_t num, | |
52 | const char *file, int line); | |
53 | int CRYPTO_secure_allocated(const void *ptr); | |
54 | void OPENSSL_cleanse(void *ptr, size_t len); | |
55 | unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); | |
56 | ||
57 | /* Functions offered by the provider to libcrypto */ | |
58 | void provider_teardown(void *provctx); | |
59 | const OSSL_ITEM *provider_get_param_types(void *provctx); | |
60 | int provider_get_params(void *provctx, OSSL_PARAM params[]); | |
61 | const OSSL_ALGORITHM *provider_query_operation(void *provctx, | |
62 | int operation_id, | |
63 | const int *no_store); | |
64 | const OSSL_ITEM *provider_get_reason_strings(void *provctx); | |
65 | ||
66 | =head1 DESCRIPTION | |
67 | ||
68 | All "functions" mentioned here are passed as function pointers between | |
69 | F<libcrypto> and the provider in B<OSSL_DISPATCH> arrays, in the call | |
70 | of the provider initialization function. See L<provider(7)/Provider> | |
71 | for a description of the initialization function. | |
72 | ||
73 | All these "functions" have a corresponding function type definition | |
74 | named B<OSSL_{name}_fn>, and a helper function to retrieve the | |
75 | function pointer from a B<OSSL_DISPATCH> element named | |
76 | B<OSSL_get_{name}>. | |
77 | For example, the "function" core_get_param_types() has these: | |
78 | ||
79 | typedef OSSL_ITEM * | |
80 | (OSSL_core_get_param_types_fn)(const OSSL_PROVIDER *prov); | |
81 | static ossl_inline OSSL_NAME_core_get_param_types_fn | |
82 | OSSL_get_core_get_param_types(const OSSL_DISPATCH *opf); | |
83 | ||
84 | B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as | |
85 | macros in L<openssl-core_numbers.h(7)>, as follows: | |
86 | ||
87 | For I<in> (the B<OSSL_DISPATCH> array passed from F<libcrypto> to the | |
88 | provider): | |
89 | ||
90 | core_get_param_types OSSL_FUNC_CORE_GET_PARAM_TYPES | |
91 | core_get_params OSSL_FUNC_CORE_GET_PARAMS | |
92 | core_thread_start OSSL_FUNC_CORE_THREAD_START | |
d4c69c69 | 93 | core_get_library_context OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT |
49c64346 RL |
94 | core_new_error OSSL_FUNC_CORE_NEW_ERROR |
95 | core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG | |
96 | core_set_error OSSL_FUNC_CORE_SET_ERROR | |
d4c69c69 RL |
97 | CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC |
98 | CRYPTO_zalloc OSSL_FUNC_CRYPTO_ZALLOC | |
99 | CRYPTO_memdup OSSL_FUNC_CRYPTO_MEMDUP | |
100 | CRYPTO_strdup OSSL_FUNC_CRYPTO_STRDUP | |
101 | CRYPTO_strndup OSSL_FUNC_CRYPTO_STRNDUP | |
102 | CRYPTO_free OSSL_FUNC_CRYPTO_FREE | |
103 | CRYPTO_clear_free OSSL_FUNC_CRYPTO_CLEAR_FREE | |
104 | CRYPTO_realloc OSSL_FUNC_CRYPTO_REALLOC | |
105 | CRYPTO_clear_realloc OSSL_FUNC_CRYPTO_CLEAR_REALLOC | |
106 | CRYPTO_secure_malloc OSSL_FUNC_CRYPTO_SECURE_MALLOC | |
107 | CRYPTO_secure_zalloc OSSL_FUNC_CRYPTO_SECURE_ZALLOC | |
108 | CRYPTO_secure_free OSSL_FUNC_CRYPTO_SECURE_FREE | |
109 | CRYPTO_secure_clear_free OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE | |
110 | CRYPTO_secure_allocated OSSL_FUNC_CRYPTO_SECURE_ALLOCATED | |
111 | OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE | |
112 | OPENSSL_hexstr2buf OSSL_FUNC_OPENSSL_HEXSTR2BUF | |
113 | ||
114 | For I<*out> (the B<OSSL_DISPATCH> array passed from the provider to | |
115 | F<libcrypto>): | |
116 | ||
117 | provider_teardown OSSL_FUNC_PROVIDER_TEARDOWN | |
118 | provider_get_param_types OSSL_FUNC_PROVIDER_GET_PARAM_TYPES | |
119 | provider_get_params OSSL_FUNC_PROVIDER_GET_PARAMS | |
120 | provider_query_operation OSSL_FUNC_PROVIDER_QUERY_OPERATION | |
121 | provider_get_reason_strings OSSL_FUNC_PROVIDER_GET_REASON_STRINGS | |
122 | ||
123 | =head2 Core functions | |
124 | ||
125 | core_get_param_types() returns a constant array of descriptor | |
126 | B<OSSL_PARAM>, for parameters that core_get_params() can handle. | |
127 | ||
128 | core_get_params() retrieves I<prov> parameters from the core. | |
129 | See L</Core parameters> below for a description of currently known | |
130 | parameters. | |
131 | ||
132 | =for comment core_thread_start() TBA | |
133 | ||
49c64346 RL |
134 | core_get_library_context() retrieves the library context in which the |
135 | B<OSSL_PROVIDER> object I<prov> is stored. | |
136 | This may sometimes be useful if the provider wishes to store a | |
137 | reference to its context in the same library context. | |
138 | ||
139 | core_new_error(), core_set_error_debug() and core_set_error() are | |
140 | building blocks for reporting an error back to the core, with | |
d4c69c69 | 141 | reference to the provider object I<prov>. |
49c64346 RL |
142 | |
143 | =over 4 | |
144 | ||
145 | =item core_new_error() | |
146 | ||
147 | allocates a new thread specific error record. | |
148 | ||
149 | This corresponds to the OpenSSL function L<ERR_new(3)>. | |
150 | ||
151 | =item core_set_error_debug() | |
152 | ||
153 | sets debugging information in the current thread specific error | |
154 | record. | |
155 | The debugging information includes the name of the file I<file>, the | |
156 | line I<line> and the function name I<func> where the error occured. | |
157 | ||
158 | This corresponds to the OpenSSL function L<ERR_set_debug(3)>. | |
159 | ||
160 | =item core_set_error() | |
161 | ||
162 | sets the I<reason> for the error, along with any addition data. | |
d4c69c69 RL |
163 | The I<reason> is a number defined by the provider and used to index |
164 | the reason strings table that's returned by | |
165 | provider_get_reason_strings(). | |
49c64346 RL |
166 | The additional data is given as a format string I<fmt> and a set of |
167 | arguments I<args>, which are treated in the same manner as with | |
168 | BIO_vsnprintf(). | |
d4c69c69 RL |
169 | I<file> and I<line> may also be passed to indicate exactly where the |
170 | error occured or was reported. | |
d4c69c69 | 171 | |
49c64346 | 172 | This corresponds to the OpenSSL function L<ERR_vset_error(3)>. |
d4c69c69 | 173 | |
49c64346 | 174 | =back |
d4c69c69 RL |
175 | |
176 | CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_memdup(), CRYPTO_strdup(), | |
177 | CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(), | |
178 | CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(), | |
179 | CRYPTO_secure_zalloc(), CRYPTO_secure_free(), | |
180 | CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(), | |
181 | OPENSSL_cleanse(), and OPENSSL_hexstr2buf() correspond exactly to the | |
182 | public functions with the same name. | |
183 | As a matter of fact, the pointers in the B<OSSL_DISPATCH> array are | |
184 | direct pointers to those public functions. | |
185 | ||
186 | =head2 Provider functions | |
187 | ||
188 | provider_teardown() is called when a provider is shut down and removed | |
189 | from the core's provider store. | |
190 | It must free the passed I<provctx>. | |
191 | ||
192 | provider_get_param_types() should return a constant array of | |
193 | descriptor B<OSSL_PARAM>, for parameters that provider_get_params() | |
194 | can handle. | |
195 | ||
196 | provider_get_params() should process the B<OSSL_PARAM> array | |
197 | I<params>, setting the values of the parameters it understands. | |
198 | ||
199 | provider_query_operation() should return a constant B<OSSL_ALGORITHM> | |
200 | that corresponds to the given I<operation_id>. | |
201 | It should indicate if the core may store a reference to this array by | |
202 | setting I<*no_store> to 0 (core may store a reference) or 1 (core may | |
203 | not store a reference). | |
204 | ||
205 | provider_get_reason_strings() should return a constant B<OSSL_ITEM> | |
206 | array that provides reason strings for reason codes the provider may | |
207 | use when reporting errors using core_put_error(). | |
208 | ||
209 | None of these functions are mandatory, but a provider is fairly | |
210 | useless without at least provider_query_operation(), and | |
211 | provider_get_param_types() is fairly useless if not accompanied by | |
212 | provider_get_params(). | |
213 | ||
214 | =head2 Core parameters | |
215 | ||
216 | core_get_params() understands the following known parameters: | |
217 | ||
218 | =over 4 | |
219 | ||
220 | =item "openssl-version" | |
221 | ||
222 | This is a B<OSSL_PARAM_UTF8_PTR> type of parameter, pointing at the | |
223 | OpenSSL libraries' full version string, i.e. the string expanded from | |
224 | the macro B<OPENSSL_VERSION_STR>. | |
225 | ||
226 | =item "provider-name" | |
227 | ||
228 | This is a B<OSSL_PARAM_UTF8_PTR> type of parameter, pointing at the | |
229 | OpenSSL libraries' idea of what the calling provider is called. | |
230 | ||
231 | =back | |
232 | ||
233 | Additionally, provider specific configuration parameters from the | |
234 | config file are available, in dotted name form. | |
235 | The dotted name form is a concatenation of section names and final | |
236 | config command name separated by periods. | |
237 | ||
238 | For example, let's say we have the following config example: | |
239 | ||
240 | openssl_conf = openssl_init | |
241 | ||
242 | [openssl_init] | |
243 | providers = providers_sect | |
244 | ||
245 | [providers_sect] | |
246 | foo = foo_sect | |
247 | ||
248 | [foo_sect] | |
249 | activate = 1 | |
250 | data1 = 2 | |
251 | data2 = str | |
252 | more = foo_more | |
253 | ||
254 | [foo_more] | |
255 | data3 = foo,bar | |
256 | ||
257 | The provider will have these additional parameters available: | |
258 | ||
259 | =over 4 | |
260 | ||
261 | =item "activate" | |
262 | ||
263 | pointing at the string "1" | |
264 | ||
265 | =item "data1" | |
266 | ||
267 | pointing at the string "2" | |
268 | ||
269 | =item "data2" | |
270 | ||
271 | pointing at the string "str" | |
272 | ||
273 | =item "more.data3" | |
274 | ||
275 | pointing at the string "foo,bar" | |
276 | ||
277 | =back | |
278 | ||
279 | For more information on handling parameters, see L<OSSL_PARAM(3)> as | |
280 | L<OSSL_PARAM_int(3)>. | |
281 | ||
282 | =head1 EXAMPLES | |
283 | ||
284 | This is an example of a simple provider made available as a | |
285 | dynamically loadable module. | |
286 | It implements the fictitious algorithm C<FOO> for the fictitious | |
287 | operation C<BAR>. | |
288 | ||
289 | #include <malloc.h> | |
290 | #include <openssl/core.h> | |
291 | #include <openssl/core_numbers.h> | |
292 | ||
293 | /* Errors used in this provider */ | |
294 | #define E_MALLOC 1 | |
295 | ||
296 | static const OSSL_ITEM reasons[] = { | |
297 | { E_MALLOC, "memory allocation failure" }. | |
298 | { 0, NULL } /* Termination */ | |
299 | }; | |
300 | ||
301 | /* | |
302 | * To ensure we get the function signature right, forward declare | |
303 | * them using function types provided by openssl/core_numbers.h | |
304 | */ | |
305 | OSSL_OP_bar_newctx_fn foo_newctx; | |
306 | OSSL_OP_bar_freectx_fn foo_freectx; | |
307 | OSSL_OP_bar_init_fn foo_init; | |
308 | OSSL_OP_bar_update_fn foo_update; | |
309 | OSSL_OP_bar_final_fn foo_final; | |
310 | ||
311 | OSSL_provider_query_operation_fn p_query; | |
312 | OSSL_provider_get_reason_strings_fn p_reasons; | |
313 | OSSL_provider_teardown_fn p_teardown; | |
314 | ||
315 | OSSL_provider_init_fn OSSL_provider_init; | |
316 | ||
317 | OSSL_core_put_error *c_put_error = NULL; | |
318 | ||
319 | /* Provider context */ | |
320 | struct prov_ctx_st { | |
321 | OSSL_PROVIDER *prov; | |
322 | } | |
323 | ||
324 | /* operation context for the algorithm FOO */ | |
325 | struct foo_ctx_st { | |
326 | struct prov_ctx_st *provctx; | |
327 | int b; | |
328 | }; | |
329 | ||
330 | static void *foo_newctx(void *provctx) | |
331 | { | |
332 | struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx)); | |
333 | ||
334 | if (fooctx != NULL) | |
335 | fooctx->provctx = provctx; | |
336 | else | |
337 | c_put_error(provctx->prov, E_MALLOC, __FILE__, __LINE__); | |
338 | return fooctx; | |
339 | } | |
340 | ||
341 | static void foo_freectx(void *fooctx) | |
342 | { | |
343 | free(fooctx); | |
344 | } | |
345 | ||
346 | static int foo_init(void *vfooctx) | |
347 | { | |
348 | struct foo_ctx_st *fooctx = vfooctx; | |
349 | ||
350 | fooctx->b = 0x33; | |
351 | } | |
352 | ||
353 | static int foo_update(void *vfooctx, unsigned char *in, size_t inl) | |
354 | { | |
355 | struct foo_ctx_st *fooctx = vfooctx; | |
356 | ||
357 | /* did you expect something serious? */ | |
358 | if (inl == 0) | |
359 | return 1; | |
360 | for (; inl-- > 0; in++) | |
361 | *in ^= fooctx->b; | |
362 | return 1; | |
363 | } | |
364 | ||
365 | static int foo_final(void *vfooctx) | |
366 | { | |
367 | struct foo_ctx_st *fooctx = vfooctx; | |
368 | ||
369 | fooctx->b = 0x66; | |
370 | } | |
371 | ||
372 | static const OSSL_DISPATCH foo_fns[] = { | |
373 | { OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx }, | |
374 | { OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx }, | |
375 | { OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init }, | |
376 | { OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update }, | |
377 | { OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final }, | |
378 | { 0, NULL } | |
379 | }; | |
380 | ||
381 | static const OSSL_ALGORITHM bars[] = { | |
382 | { "FOO", "provider=chumbawamba", foo_fns }, | |
383 | { NULL, NULL, NULL } | |
384 | }; | |
385 | ||
386 | static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id, | |
387 | int *no_store) | |
388 | { | |
389 | switch (operation_id) { | |
390 | case OSSL_OP_BAR: | |
391 | return bars; | |
392 | } | |
393 | return NULL; | |
394 | } | |
395 | ||
396 | static const OSSL_ITEM *p_reasons(void *provctx) | |
397 | { | |
398 | return reasons; | |
399 | } | |
400 | ||
401 | static void p_teardown(void *provctx) | |
402 | { | |
403 | free(provctx); | |
404 | } | |
405 | ||
406 | static const OSSL_DISPATCH prov_fns[] = { | |
407 | { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown }, | |
408 | { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query }, | |
409 | { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons }, | |
410 | { 0, NULL } | |
411 | }; | |
412 | ||
413 | int OSSL_provider_init(const OSSL_PROVIDER *provider, | |
414 | const OSSL_DISPATCH *in, | |
415 | const OSSL_DISPATCH **out, | |
416 | void **provctx) | |
417 | { | |
418 | struct prov_ctx_st *pctx = NULL; | |
419 | ||
420 | for (; in->function_id != 0; in++) | |
421 | switch (in->function_id) { | |
422 | case OSSL_FUNC_CORE_PUT_ERROR: | |
423 | c_put_error = OSSL_get_core_put_error(in); | |
424 | break; | |
425 | } | |
426 | ||
427 | *out = prov_fns; | |
428 | ||
429 | if ((pctx = malloc(sizeof(*pctx))) == NULL) { | |
430 | /* | |
431 | * ALEA IACTA EST, if the core retrieves the reason table | |
432 | * regardless, that string will be displayed, otherwise not. | |
433 | */ | |
434 | c_put_error(provider, E_MALLOC, __FILE__, __LINE__); | |
435 | return 0; | |
436 | } | |
437 | return 1; | |
438 | } | |
439 | ||
440 | This relies on a few things existing in F<openssl/core_numbers.h>: | |
441 | ||
442 | #define OSSL_OP_BAR 4711 | |
443 | ||
444 | #define OSSL_FUNC_BAR_NEWCTX 1 | |
445 | typedef void *(OSSL_OP_bar_newctx_fn)(void *provctx); | |
446 | static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf) | |
447 | { return (OSSL_OP_bar_newctx_fn *)opf->function; } | |
448 | ||
449 | #define OSSL_FUNC_BAR_FREECTX 2 | |
450 | typedef void (OSSL_OP_bar_freectx_fn)(void *ctx); | |
451 | static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf) | |
452 | { return (OSSL_OP_bar_freectx_fn *)opf->function; } | |
453 | ||
454 | #define OSSL_FUNC_BAR_INIT 3 | |
455 | typedef void *(OSSL_OP_bar_init_fn)(void *ctx); | |
456 | static ossl_inline OSSL_get_bar_init(const OSSL_DISPATCH *opf) | |
457 | { return (OSSL_OP_bar_init_fn *)opf->function; } | |
458 | ||
459 | #define OSSL_FUNC_BAR_UPDATE 4 | |
460 | typedef void *(OSSL_OP_bar_update_fn)(void *ctx, | |
461 | unsigned char *in, size_t inl); | |
462 | static ossl_inline OSSL_get_bar_update(const OSSL_DISPATCH *opf) | |
463 | { return (OSSL_OP_bar_update_fn *)opf->function; } | |
464 | ||
465 | #define OSSL_FUNC_BAR_FINAL 5 | |
466 | typedef void *(OSSL_OP_bar_final_fn)(void *ctx); | |
467 | static ossl_inline OSSL_get_bar_final(const OSSL_DISPATCH *opf) | |
468 | { return (OSSL_OP_bar_final_fn *)opf->function; } | |
469 | ||
470 | =head1 SEE ALSO | |
471 | ||
472 | L<provider(7)> | |
473 | ||
474 | =head1 HISTORY | |
475 | ||
476 | The concept of providers and everything surrounding them was | |
477 | introduced in OpenSSL 3.0. | |
478 | ||
479 | =head1 COPYRIGHT | |
480 | ||
481 | Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. | |
482 | ||
483 | Licensed under the Apache License 2.0 (the "License"). You may not use | |
484 | this file except in compliance with the License. You can obtain a copy | |
485 | in the file LICENSE in the source distribution or at | |
486 | L<https://www.openssl.org/source/license.html>. | |
487 | ||
488 | =cut |