1*b077aed3SPierre Pronchery=pod
2*b077aed3SPierre Pronchery
3*b077aed3SPierre Pronchery=head1 NAME
4*b077aed3SPierre Pronchery
5*b077aed3SPierre Proncheryprovider-base
6*b077aed3SPierre Pronchery- The basic OpenSSL library E<lt>-E<gt> provider functions
7*b077aed3SPierre Pronchery
8*b077aed3SPierre Pronchery=head1 SYNOPSIS
9*b077aed3SPierre Pronchery
10*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
11*b077aed3SPierre Pronchery
12*b077aed3SPierre Pronchery /*
13*b077aed3SPierre Pronchery  * None of these are actual functions, but are displayed like this for
14*b077aed3SPierre Pronchery  * the function signatures for functions that are offered as function
15*b077aed3SPierre Pronchery  * pointers in OSSL_DISPATCH arrays.
16*b077aed3SPierre Pronchery  */
17*b077aed3SPierre Pronchery
18*b077aed3SPierre Pronchery /* Functions offered by libcrypto to the providers */
19*b077aed3SPierre Pronchery const OSSL_ITEM *core_gettable_params(const OSSL_CORE_HANDLE *handle);
20*b077aed3SPierre Pronchery int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]);
21*b077aed3SPierre Pronchery
22*b077aed3SPierre Pronchery typedef void (*OSSL_thread_stop_handler_fn)(void *arg);
23*b077aed3SPierre Pronchery int core_thread_start(const OSSL_CORE_HANDLE *handle,
24*b077aed3SPierre Pronchery                       OSSL_thread_stop_handler_fn handfn,
25*b077aed3SPierre Pronchery                       void *arg);
26*b077aed3SPierre Pronchery
27*b077aed3SPierre Pronchery OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle);
28*b077aed3SPierre Pronchery void core_new_error(const OSSL_CORE_HANDLE *handle);
29*b077aed3SPierre Pronchery void core_set_error_debug(const OSSL_CORE_HANDLE *handle,
30*b077aed3SPierre Pronchery                           const char *file, int line, const char *func);
31*b077aed3SPierre Pronchery void core_vset_error(const OSSL_CORE_HANDLE *handle,
32*b077aed3SPierre Pronchery                      uint32_t reason, const char *fmt, va_list args);
33*b077aed3SPierre Pronchery
34*b077aed3SPierre Pronchery int core_obj_add_sigid(const OSSL_CORE_HANDLE *prov, const char  *sign_name,
35*b077aed3SPierre Pronchery                        const char *digest_name, const char *pkey_name);
36*b077aed3SPierre Pronchery int core_obj_create(const OSSL_CORE_HANDLE *handle, const char *oid,
37*b077aed3SPierre Pronchery                     const char *sn, const char *ln);
38*b077aed3SPierre Pronchery
39*b077aed3SPierre Pronchery /*
40*b077aed3SPierre Pronchery  * Some OpenSSL functionality is directly offered to providers via
41*b077aed3SPierre Pronchery  * dispatch
42*b077aed3SPierre Pronchery  */
43*b077aed3SPierre Pronchery void *CRYPTO_malloc(size_t num, const char *file, int line);
44*b077aed3SPierre Pronchery void *CRYPTO_zalloc(size_t num, const char *file, int line);
45*b077aed3SPierre Pronchery void CRYPTO_free(void *ptr, const char *file, int line);
46*b077aed3SPierre Pronchery void CRYPTO_clear_free(void *ptr, size_t num,
47*b077aed3SPierre Pronchery                        const char *file, int line);
48*b077aed3SPierre Pronchery void *CRYPTO_realloc(void *addr, size_t num,
49*b077aed3SPierre Pronchery                      const char *file, int line);
50*b077aed3SPierre Pronchery void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
51*b077aed3SPierre Pronchery                            const char *file, int line);
52*b077aed3SPierre Pronchery void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
53*b077aed3SPierre Pronchery void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
54*b077aed3SPierre Pronchery void CRYPTO_secure_free(void *ptr, const char *file, int line);
55*b077aed3SPierre Pronchery void CRYPTO_secure_clear_free(void *ptr, size_t num,
56*b077aed3SPierre Pronchery                               const char *file, int line);
57*b077aed3SPierre Pronchery int CRYPTO_secure_allocated(const void *ptr);
58*b077aed3SPierre Pronchery void OPENSSL_cleanse(void *ptr, size_t len);
59*b077aed3SPierre Pronchery
60*b077aed3SPierre Pronchery unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen);
61*b077aed3SPierre Pronchery
62*b077aed3SPierre Pronchery OSSL_CORE_BIO *BIO_new_file(const char *filename, const char *mode);
63*b077aed3SPierre Pronchery OSSL_CORE_BIO *BIO_new_membuf(const void *buf, int len);
64*b077aed3SPierre Pronchery int BIO_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
65*b077aed3SPierre Pronchery                 size_t *bytes_read);
66*b077aed3SPierre Pronchery int BIO_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
67*b077aed3SPierre Pronchery                  size_t *written);
68*b077aed3SPierre Pronchery int BIO_up_ref(OSSL_CORE_BIO *bio);
69*b077aed3SPierre Pronchery int BIO_free(OSSL_CORE_BIO *bio);
70*b077aed3SPierre Pronchery int BIO_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list args);
71*b077aed3SPierre Pronchery int BIO_vsnprintf(char *buf, size_t n, const char *fmt, va_list args);
72*b077aed3SPierre Pronchery
73*b077aed3SPierre Pronchery void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb,
74*b077aed3SPierre Pronchery                                  void *cbarg);
75*b077aed3SPierre Pronchery
76*b077aed3SPierre Pronchery size_t get_entropy(const OSSL_CORE_HANDLE *handle,
77*b077aed3SPierre Pronchery                    unsigned char **pout, int entropy,
78*b077aed3SPierre Pronchery                    size_t min_len, size_t max_len);
79*b077aed3SPierre Pronchery void cleanup_entropy(const OSSL_CORE_HANDLE *handle,
80*b077aed3SPierre Pronchery                      unsigned char *buf, size_t len);
81*b077aed3SPierre Pronchery size_t get_nonce(const OSSL_CORE_HANDLE *handle,
82*b077aed3SPierre Pronchery                  unsigned char **pout, size_t min_len, size_t max_len,
83*b077aed3SPierre Pronchery                  const void *salt, size_t salt_len);
84*b077aed3SPierre Pronchery void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
85*b077aed3SPierre Pronchery                    unsigned char *buf, size_t len);
86*b077aed3SPierre Pronchery
87*b077aed3SPierre Pronchery /* Functions for querying the providers in the application library context */
88*b077aed3SPierre Pronchery int provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
89*b077aed3SPierre Pronchery                     int (*create_cb)(const OSSL_CORE_HANDLE *provider,
90*b077aed3SPierre Pronchery                                      void *cbdata),
91*b077aed3SPierre Pronchery                     int (*remove_cb)(const OSSL_CORE_HANDLE *provider,
92*b077aed3SPierre Pronchery                                      void *cbdata),
93*b077aed3SPierre Pronchery                     int (*global_props_cb)(const char *props, void *cbdata),
94*b077aed3SPierre Pronchery                     void *cbdata);
95*b077aed3SPierre Pronchery void provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle);
96*b077aed3SPierre Pronchery const char *provider_name(const OSSL_CORE_HANDLE *prov);
97*b077aed3SPierre Pronchery void *provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov);
98*b077aed3SPierre Pronchery const OSSL_DISPATCH *provider_get0_dispatch(const OSSL_CORE_HANDLE *prov);
99*b077aed3SPierre Pronchery int provider_up_ref(const OSSL_CORE_HANDLE *prov, int activate);
100*b077aed3SPierre Pronchery int provider_free(const OSSL_CORE_HANDLE *prov, int deactivate);
101*b077aed3SPierre Pronchery
102*b077aed3SPierre Pronchery /* Functions offered by the provider to libcrypto */
103*b077aed3SPierre Pronchery void provider_teardown(void *provctx);
104*b077aed3SPierre Pronchery const OSSL_ITEM *provider_gettable_params(void *provctx);
105*b077aed3SPierre Pronchery int provider_get_params(void *provctx, OSSL_PARAM params[]);
106*b077aed3SPierre Pronchery const OSSL_ALGORITHM *provider_query_operation(void *provctx,
107*b077aed3SPierre Pronchery                                                int operation_id,
108*b077aed3SPierre Pronchery                                                const int *no_store);
109*b077aed3SPierre Pronchery void provider_unquery_operation(void *provctx, int operation_id,
110*b077aed3SPierre Pronchery                                 const OSSL_ALGORITHM *algs);
111*b077aed3SPierre Pronchery const OSSL_ITEM *provider_get_reason_strings(void *provctx);
112*b077aed3SPierre Pronchery int provider_get_capabilities(void *provctx, const char *capability,
113*b077aed3SPierre Pronchery                               OSSL_CALLBACK *cb, void *arg);
114*b077aed3SPierre Pronchery int provider_self_test(void *provctx);
115*b077aed3SPierre Pronchery
116*b077aed3SPierre Pronchery=head1 DESCRIPTION
117*b077aed3SPierre Pronchery
118*b077aed3SPierre ProncheryAll "functions" mentioned here are passed as function pointers between
119*b077aed3SPierre ProncheryF<libcrypto> and the provider in L<OSSL_DISPATCH(3)> arrays, in the call
120*b077aed3SPierre Proncheryof the provider initialization function.  See L<provider(7)/Provider>
121*b077aed3SPierre Proncheryfor a description of the initialization function. They are known as "upcalls".
122*b077aed3SPierre Pronchery
123*b077aed3SPierre ProncheryAll these "functions" have a corresponding function type definition
124*b077aed3SPierre Proncherynamed B<OSSL_FUNC_{name}_fn>, and a helper function to retrieve the
125*b077aed3SPierre Proncheryfunction pointer from a L<OSSL_DISPATCH(3)> element named
126*b077aed3SPierre ProncheryB<OSSL_FUNC_{name}>.
127*b077aed3SPierre ProncheryFor example, the "function" core_gettable_params() has these:
128*b077aed3SPierre Pronchery
129*b077aed3SPierre Pronchery typedef OSSL_PARAM *
130*b077aed3SPierre Pronchery     (OSSL_FUNC_core_gettable_params_fn)(const OSSL_CORE_HANDLE *handle);
131*b077aed3SPierre Pronchery static ossl_inline OSSL_NAME_core_gettable_params_fn
132*b077aed3SPierre Pronchery     OSSL_FUNC_core_gettable_params(const OSSL_DISPATCH *opf);
133*b077aed3SPierre Pronchery
134*b077aed3SPierre ProncheryL<OSSL_DISPATCH(3)> arrays are indexed by numbers that are provided as
135*b077aed3SPierre Proncherymacros in L<openssl-core_dispatch.h(7)>, as follows:
136*b077aed3SPierre Pronchery
137*b077aed3SPierre ProncheryFor I<in> (the L<OSSL_DISPATCH(3)> array passed from F<libcrypto> to the
138*b077aed3SPierre Proncheryprovider):
139*b077aed3SPierre Pronchery
140*b077aed3SPierre Pronchery core_gettable_params           OSSL_FUNC_CORE_GETTABLE_PARAMS
141*b077aed3SPierre Pronchery core_get_params                OSSL_FUNC_CORE_GET_PARAMS
142*b077aed3SPierre Pronchery core_thread_start              OSSL_FUNC_CORE_THREAD_START
143*b077aed3SPierre Pronchery core_get_libctx                OSSL_FUNC_CORE_GET_LIBCTX
144*b077aed3SPierre Pronchery core_new_error                 OSSL_FUNC_CORE_NEW_ERROR
145*b077aed3SPierre Pronchery core_set_error_debug           OSSL_FUNC_CORE_SET_ERROR_DEBUG
146*b077aed3SPierre Pronchery core_vset_error                OSSL_FUNC_CORE_VSET_ERROR
147*b077aed3SPierre Pronchery core_obj_add_sigid             OSSL_FUNC_CORE_OBJ_ADD_SIGID
148*b077aed3SPierre Pronchery core_obj_create                OSSL_FUNC_CORE_OBJ_CREATE
149*b077aed3SPierre Pronchery CRYPTO_malloc                  OSSL_FUNC_CRYPTO_MALLOC
150*b077aed3SPierre Pronchery CRYPTO_zalloc                  OSSL_FUNC_CRYPTO_ZALLOC
151*b077aed3SPierre Pronchery CRYPTO_free                    OSSL_FUNC_CRYPTO_FREE
152*b077aed3SPierre Pronchery CRYPTO_clear_free              OSSL_FUNC_CRYPTO_CLEAR_FREE
153*b077aed3SPierre Pronchery CRYPTO_realloc                 OSSL_FUNC_CRYPTO_REALLOC
154*b077aed3SPierre Pronchery CRYPTO_clear_realloc           OSSL_FUNC_CRYPTO_CLEAR_REALLOC
155*b077aed3SPierre Pronchery CRYPTO_secure_malloc           OSSL_FUNC_CRYPTO_SECURE_MALLOC
156*b077aed3SPierre Pronchery CRYPTO_secure_zalloc           OSSL_FUNC_CRYPTO_SECURE_ZALLOC
157*b077aed3SPierre Pronchery CRYPTO_secure_free             OSSL_FUNC_CRYPTO_SECURE_FREE
158*b077aed3SPierre Pronchery CRYPTO_secure_clear_free       OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE
159*b077aed3SPierre Pronchery CRYPTO_secure_allocated        OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
160*b077aed3SPierre Pronchery BIO_new_file                   OSSL_FUNC_BIO_NEW_FILE
161*b077aed3SPierre Pronchery BIO_new_mem_buf                OSSL_FUNC_BIO_NEW_MEMBUF
162*b077aed3SPierre Pronchery BIO_read_ex                    OSSL_FUNC_BIO_READ_EX
163*b077aed3SPierre Pronchery BIO_write_ex                   OSSL_FUNC_BIO_WRITE_EX
164*b077aed3SPierre Pronchery BIO_up_ref                     OSSL_FUNC_BIO_UP_REF
165*b077aed3SPierre Pronchery BIO_free                       OSSL_FUNC_BIO_FREE
166*b077aed3SPierre Pronchery BIO_vprintf                    OSSL_FUNC_BIO_VPRINTF
167*b077aed3SPierre Pronchery BIO_vsnprintf                  OSSL_FUNC_BIO_VSNPRINTF
168*b077aed3SPierre Pronchery BIO_puts                       OSSL_FUNC_BIO_PUTS
169*b077aed3SPierre Pronchery BIO_gets                       OSSL_FUNC_BIO_GETS
170*b077aed3SPierre Pronchery BIO_ctrl                       OSSL_FUNC_BIO_CTRL
171*b077aed3SPierre Pronchery OPENSSL_cleanse                OSSL_FUNC_OPENSSL_CLEANSE
172*b077aed3SPierre Pronchery OSSL_SELF_TEST_set_callback    OSSL_FUNC_SELF_TEST_CB
173*b077aed3SPierre Pronchery ossl_rand_get_entropy          OSSL_FUNC_GET_ENTROPY
174*b077aed3SPierre Pronchery ossl_rand_cleanup_entropy      OSSL_FUNC_CLEANUP_ENTROPY
175*b077aed3SPierre Pronchery ossl_rand_get_nonce            OSSL_FUNC_GET_NONCE
176*b077aed3SPierre Pronchery ossl_rand_cleanup_nonce        OSSL_FUNC_CLEANUP_NONCE
177*b077aed3SPierre Pronchery provider_register_child_cb     OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB
178*b077aed3SPierre Pronchery provider_deregister_child_cb   OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB
179*b077aed3SPierre Pronchery provider_name                  OSSL_FUNC_PROVIDER_NAME
180*b077aed3SPierre Pronchery provider_get0_provider_ctx     OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX
181*b077aed3SPierre Pronchery provider_get0_dispatch         OSSL_FUNC_PROVIDER_GET0_DISPATCH
182*b077aed3SPierre Pronchery provider_up_ref                OSSL_FUNC_PROVIDER_UP_REF
183*b077aed3SPierre Pronchery provider_free                  OSSL_FUNC_PROVIDER_FREE
184*b077aed3SPierre Pronchery
185*b077aed3SPierre ProncheryFor I<*out> (the L<OSSL_DISPATCH(3)> array passed from the provider to
186*b077aed3SPierre ProncheryF<libcrypto>):
187*b077aed3SPierre Pronchery
188*b077aed3SPierre Pronchery provider_teardown              OSSL_FUNC_PROVIDER_TEARDOWN
189*b077aed3SPierre Pronchery provider_gettable_params       OSSL_FUNC_PROVIDER_GETTABLE_PARAMS
190*b077aed3SPierre Pronchery provider_get_params            OSSL_FUNC_PROVIDER_GET_PARAMS
191*b077aed3SPierre Pronchery provider_query_operation       OSSL_FUNC_PROVIDER_QUERY_OPERATION
192*b077aed3SPierre Pronchery provider_unquery_operation     OSSL_FUNC_PROVIDER_UNQUERY_OPERATION
193*b077aed3SPierre Pronchery provider_get_reason_strings    OSSL_FUNC_PROVIDER_GET_REASON_STRINGS
194*b077aed3SPierre Pronchery provider_get_capabilities      OSSL_FUNC_PROVIDER_GET_CAPABILITIES
195*b077aed3SPierre Pronchery provider_self_test             OSSL_FUNC_PROVIDER_SELF_TEST
196*b077aed3SPierre Pronchery
197*b077aed3SPierre Pronchery=head2 Core functions
198*b077aed3SPierre Pronchery
199*b077aed3SPierre Proncherycore_gettable_params() returns a constant array of descriptor
200*b077aed3SPierre ProncheryL<OSSL_PARAM(3)>, for parameters that core_get_params() can handle.
201*b077aed3SPierre Pronchery
202*b077aed3SPierre Proncherycore_get_params() retrieves parameters from the core for the given I<handle>.
203*b077aed3SPierre ProncherySee L</Core parameters> below for a description of currently known
204*b077aed3SPierre Proncheryparameters.
205*b077aed3SPierre Pronchery
206*b077aed3SPierre ProncheryThe core_thread_start() function informs the core that the provider has stated
207*b077aed3SPierre Proncheryan interest in the current thread. The core will inform the provider when the
208*b077aed3SPierre Proncherythread eventually stops. It must be passed the I<handle> for this provider, as
209*b077aed3SPierre Proncherywell as a callback I<handfn> which will be called when the thread stops. The
210*b077aed3SPierre Proncherycallback will subsequently be called, with the supplied argument I<arg>, from
211*b077aed3SPierre Proncherythe thread that is stopping and gets passed the provider context as an
212*b077aed3SPierre Proncheryargument. This may be useful to perform thread specific clean up such as
213*b077aed3SPierre Proncheryfreeing thread local variables.
214*b077aed3SPierre Pronchery
215*b077aed3SPierre Proncherycore_get_libctx() retrieves the core context in which the library
216*b077aed3SPierre Proncheryobject for the current provider is stored, accessible through the I<handle>.
217*b077aed3SPierre ProncheryThis function is useful only for built-in providers such as the default
218*b077aed3SPierre Proncheryprovider. Never cast this to OSSL_LIB_CTX in a provider that is not
219*b077aed3SPierre Proncherybuilt-in as the OSSL_LIB_CTX of the library loading the provider might be
220*b077aed3SPierre Proncherya completely different structure than the OSSL_LIB_CTX of the library the
221*b077aed3SPierre Proncheryprovider is linked to. Use  L<OSSL_LIB_CTX_new_child(3)> instead to obtain
222*b077aed3SPierre Proncherya proper library context that is linked to the application library context.
223*b077aed3SPierre Pronchery
224*b077aed3SPierre Proncherycore_new_error(), core_set_error_debug() and core_vset_error() are
225*b077aed3SPierre Proncherybuilding blocks for reporting an error back to the core, with
226*b077aed3SPierre Proncheryreference to the I<handle>.
227*b077aed3SPierre Pronchery
228*b077aed3SPierre Pronchery=over 4
229*b077aed3SPierre Pronchery
230*b077aed3SPierre Pronchery=item core_new_error()
231*b077aed3SPierre Pronchery
232*b077aed3SPierre Proncheryallocates a new thread specific error record.
233*b077aed3SPierre Pronchery
234*b077aed3SPierre ProncheryThis corresponds to the OpenSSL function L<ERR_new(3)>.
235*b077aed3SPierre Pronchery
236*b077aed3SPierre Pronchery=item core_set_error_debug()
237*b077aed3SPierre Pronchery
238*b077aed3SPierre Proncherysets debugging information in the current thread specific error
239*b077aed3SPierre Proncheryrecord.
240*b077aed3SPierre ProncheryThe debugging information includes the name of the file I<file>, the
241*b077aed3SPierre Proncheryline I<line> and the function name I<func> where the error occurred.
242*b077aed3SPierre Pronchery
243*b077aed3SPierre ProncheryThis corresponds to the OpenSSL function L<ERR_set_debug(3)>.
244*b077aed3SPierre Pronchery
245*b077aed3SPierre Pronchery=item core_vset_error()
246*b077aed3SPierre Pronchery
247*b077aed3SPierre Proncherysets the I<reason> for the error, along with any addition data.
248*b077aed3SPierre ProncheryThe I<reason> is a number defined by the provider and used to index
249*b077aed3SPierre Proncherythe reason strings table that's returned by
250*b077aed3SPierre Proncheryprovider_get_reason_strings().
251*b077aed3SPierre ProncheryThe additional data is given as a format string I<fmt> and a set of
252*b077aed3SPierre Proncheryarguments I<args>, which are treated in the same manner as with
253*b077aed3SPierre ProncheryBIO_vsnprintf().
254*b077aed3SPierre ProncheryI<file> and I<line> may also be passed to indicate exactly where the
255*b077aed3SPierre Proncheryerror occurred or was reported.
256*b077aed3SPierre Pronchery
257*b077aed3SPierre ProncheryThis corresponds to the OpenSSL function L<ERR_vset_error(3)>.
258*b077aed3SPierre Pronchery
259*b077aed3SPierre Pronchery=back
260*b077aed3SPierre Pronchery
261*b077aed3SPierre ProncheryThe core_obj_create() function registers a new OID and associated short name
262*b077aed3SPierre ProncheryI<sn> and long name I<ln> for the given I<handle>. It is similar to the OpenSSL
263*b077aed3SPierre Proncheryfunction L<OBJ_create(3)> except that it returns 1 on success or 0 on failure.
264*b077aed3SPierre ProncheryIt will treat as success the case where the OID already exists (even if the
265*b077aed3SPierre Proncheryshort name I<sn> or long name I<ln> provided as arguments differ from those
266*b077aed3SPierre Proncheryassociated with the existing OID, in which case the new names are not
267*b077aed3SPierre Proncheryassociated).
268*b077aed3SPierre ProncheryThis function is not thread safe.
269*b077aed3SPierre Pronchery
270*b077aed3SPierre ProncheryThe core_obj_add_sigid() function registers a new composite signature algorithm
271*b077aed3SPierre Pronchery(I<sign_name>) consisting of an underlying signature algorithm (I<pkey_name>)
272*b077aed3SPierre Proncheryand digest algorithm (I<digest_name>) for the given I<handle>. It assumes that
273*b077aed3SPierre Proncherythe OIDs for the composite signature algorithm as well as for the underlying
274*b077aed3SPierre Proncherysignature and digest algorithms are either already known to OpenSSL or have been
275*b077aed3SPierre Proncheryregistered via a call to core_obj_create(). It corresponds to the OpenSSL
276*b077aed3SPierre Proncheryfunction L<OBJ_add_sigid(3)>, except that the objects are identified by name
277*b077aed3SPierre Proncheryrather than a numeric NID. Any name (OID, short name or long name) can be used
278*b077aed3SPierre Proncheryto identify the object. It will treat as success the case where the composite
279*b077aed3SPierre Proncherysignature algorithm already exists (even if registered against a different
280*b077aed3SPierre Proncheryunderlying signature or digest algorithm). For I<digest_name>, NULL or an
281*b077aed3SPierre Proncheryempty string is permissible for signature algorithms that do not need a digest
282*b077aed3SPierre Proncheryto operate correctly. The function returns 1 on success or 0 on failure.
283*b077aed3SPierre ProncheryThis function is not thread safe.
284*b077aed3SPierre Pronchery
285*b077aed3SPierre ProncheryCRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_free(), CRYPTO_clear_free(),
286*b077aed3SPierre ProncheryCRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(),
287*b077aed3SPierre ProncheryCRYPTO_secure_zalloc(), CRYPTO_secure_free(),
288*b077aed3SPierre ProncheryCRYPTO_secure_clear_free(), CRYPTO_secure_allocated(),
289*b077aed3SPierre ProncheryBIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_write_ex(), BIO_up_ref(),
290*b077aed3SPierre ProncheryBIO_free(), BIO_vprintf(), BIO_vsnprintf(), BIO_gets(), BIO_puts(),
291*b077aed3SPierre ProncheryBIO_ctrl(), OPENSSL_cleanse() and
292*b077aed3SPierre ProncheryOPENSSL_hexstr2buf() correspond exactly to the public functions with
293*b077aed3SPierre Proncherythe same name.  As a matter of fact, the pointers in the L<OSSL_DISPATCH(3)>
294*b077aed3SPierre Proncheryarray are typically direct pointers to those public functions. Note that the BIO
295*b077aed3SPierre Proncheryfunctions take an B<OSSL_CORE_BIO> type rather than the standard B<BIO>
296*b077aed3SPierre Proncherytype. This is to ensure that a provider does not mix BIOs from the core
297*b077aed3SPierre Proncherywith BIOs used on the provider side (the two are not compatible).
298*b077aed3SPierre ProncheryOSSL_SELF_TEST_set_callback() is used to set an optional callback that can be
299*b077aed3SPierre Proncherypassed into a provider. This may be ignored by a provider.
300*b077aed3SPierre Pronchery
301*b077aed3SPierre Proncheryget_entropy() retrieves seeding material from the operating system.
302*b077aed3SPierre ProncheryThe seeding material will have at least I<entropy> bytes of randomness and the
303*b077aed3SPierre Proncheryoutput will have at least I<min_len> and at most I<max_len> bytes.
304*b077aed3SPierre ProncheryThe buffer address is stored in I<*pout> and the buffer length is
305*b077aed3SPierre Proncheryreturned to the caller.  On error, zero is returned.
306*b077aed3SPierre Pronchery
307*b077aed3SPierre Proncherycleanup_entropy() is used to clean up and free the buffer returned by
308*b077aed3SPierre Proncheryget_entropy().  The entropy pointer returned by get_entropy() is passed in
309*b077aed3SPierre ProncheryB<buf> and its length in B<len>.
310*b077aed3SPierre Pronchery
311*b077aed3SPierre Proncheryget_nonce() retrieves a nonce using the passed I<salt> parameter
312*b077aed3SPierre Proncheryof length I<salt_len> and operating system specific information.
313*b077aed3SPierre ProncheryThe I<salt> should contain uniquely identifying information and this is
314*b077aed3SPierre Proncheryincluded, in an unspecified manner, as part of the output.
315*b077aed3SPierre ProncheryThe output is stored in a buffer which contains at least I<min_len> and at
316*b077aed3SPierre Proncherymost I<max_len> bytes.  The buffer address is stored in I<*pout> and the
317*b077aed3SPierre Proncherybuffer length returned to the caller.  On error, zero is returned.
318*b077aed3SPierre Pronchery
319*b077aed3SPierre Proncherycleanup_nonce() is used to clean up and free the buffer returned by
320*b077aed3SPierre Proncheryget_nonce().  The nonce pointer returned by get_nonce() is passed in
321*b077aed3SPierre ProncheryB<buf> and its length in B<len>.
322*b077aed3SPierre Pronchery
323*b077aed3SPierre Proncheryprovider_register_child_cb() registers callbacks for being informed about the
324*b077aed3SPierre Proncheryloading and unloading of providers in the application's library context.
325*b077aed3SPierre ProncheryI<handle> is this provider's handle and I<cbdata> is this provider's data
326*b077aed3SPierre Proncherythat will be passed back to the callbacks. It returns 1 on success or 0
327*b077aed3SPierre Proncheryotherwise. These callbacks may be called while holding locks in libcrypto. In
328*b077aed3SPierre Proncheryorder to avoid deadlocks the callback implementation must not be long running
329*b077aed3SPierre Proncheryand must not call other OpenSSL API functions or upcalls.
330*b077aed3SPierre Pronchery
331*b077aed3SPierre ProncheryI<create_cb> is a callback that will be called when a new provider is loaded
332*b077aed3SPierre Proncheryinto the application's library context. It is also called for any providers that
333*b077aed3SPierre Proncheryare already loaded at the point that this callback is registered. The callback
334*b077aed3SPierre Proncheryis passed the handle being used for the new provider being loadded and this
335*b077aed3SPierre Proncheryprovider's data in I<cbdata>. It should return 1 on success or 0 on failure.
336*b077aed3SPierre Pronchery
337*b077aed3SPierre ProncheryI<remove_cb> is a callback that will be called when a new provider is unloaded
338*b077aed3SPierre Proncheryfrom the application's library context. It is passed the handle being used for
339*b077aed3SPierre Proncherythe provider being unloaded and this provider's data in I<cbdata>. It should
340*b077aed3SPierre Proncheryreturn 1 on success or 0 on failure.
341*b077aed3SPierre Pronchery
342*b077aed3SPierre ProncheryI<global_props_cb> is a callback that will be called when the global properties
343*b077aed3SPierre Proncheryfrom the parent library context are changed. It should return 1 on success
344*b077aed3SPierre Proncheryor 0 on failure.
345*b077aed3SPierre Pronchery
346*b077aed3SPierre Proncheryprovider_deregister_child_cb() unregisters callbacks previously registered via
347*b077aed3SPierre Proncheryprovider_register_child_cb(). If provider_register_child_cb() has been called
348*b077aed3SPierre Proncherythen provider_deregister_child_cb() should be called at or before the point that
349*b077aed3SPierre Proncherythis provider's teardown function is called.
350*b077aed3SPierre Pronchery
351*b077aed3SPierre Proncheryprovider_name() returns a string giving the name of the provider identified by
352*b077aed3SPierre ProncheryI<handle>.
353*b077aed3SPierre Pronchery
354*b077aed3SPierre Proncheryprovider_get0_provider_ctx() returns the provider context that is associated
355*b077aed3SPierre Proncherywith the provider identified by I<prov>.
356*b077aed3SPierre Pronchery
357*b077aed3SPierre Proncheryprovider_get0_dispatch() gets the dispatch table registered by the provider
358*b077aed3SPierre Proncheryidentified by I<prov> when it initialised.
359*b077aed3SPierre Pronchery
360*b077aed3SPierre Proncheryprovider_up_ref() increments the reference count on the provider I<prov>. If
361*b077aed3SPierre ProncheryI<activate> is nonzero then the provider is also loaded if it is not already
362*b077aed3SPierre Proncheryloaded. It returns 1 on success or 0 on failure.
363*b077aed3SPierre Pronchery
364*b077aed3SPierre Proncheryprovider_free() decrements the reference count on the provider I<prov>. If
365*b077aed3SPierre ProncheryI<deactivate> is nonzero then the provider is also unloaded if it is not
366*b077aed3SPierre Proncheryalready loaded. It returns 1 on success or 0 on failure.
367*b077aed3SPierre Pronchery
368*b077aed3SPierre Pronchery=head2 Provider functions
369*b077aed3SPierre Pronchery
370*b077aed3SPierre Proncheryprovider_teardown() is called when a provider is shut down and removed
371*b077aed3SPierre Proncheryfrom the core's provider store.
372*b077aed3SPierre ProncheryIt must free the passed I<provctx>.
373*b077aed3SPierre Pronchery
374*b077aed3SPierre Proncheryprovider_gettable_params() should return a constant array of
375*b077aed3SPierre Proncherydescriptor L<OSSL_PARAM(3)>, for parameters that provider_get_params()
376*b077aed3SPierre Proncherycan handle.
377*b077aed3SPierre Pronchery
378*b077aed3SPierre Proncheryprovider_get_params() should process the L<OSSL_PARAM(3)> array
379*b077aed3SPierre ProncheryI<params>, setting the values of the parameters it understands.
380*b077aed3SPierre Pronchery
381*b077aed3SPierre Proncheryprovider_query_operation() should return a constant L<OSSL_ALGORITHM(3)>
382*b077aed3SPierre Proncherythat corresponds to the given I<operation_id>.
383*b077aed3SPierre ProncheryIt should indicate if the core may store a reference to this array by
384*b077aed3SPierre Proncherysetting I<*no_store> to 0 (core may store a reference) or 1 (core may
385*b077aed3SPierre Proncherynot store a reference).
386*b077aed3SPierre Pronchery
387*b077aed3SPierre Proncheryprovider_unquery_operation() informs the provider that the result of a
388*b077aed3SPierre Proncheryprovider_query_operation() is no longer directly required and that the function
389*b077aed3SPierre Proncherypointers have been copied.  The I<operation_id> should match that passed to
390*b077aed3SPierre Proncheryprovider_query_operation() and I<algs> should be its return value.
391*b077aed3SPierre Pronchery
392*b077aed3SPierre Proncheryprovider_get_reason_strings() should return a constant L<OSSL_ITEM(3)>
393*b077aed3SPierre Proncheryarray that provides reason strings for reason codes the provider may
394*b077aed3SPierre Proncheryuse when reporting errors using core_put_error().
395*b077aed3SPierre Pronchery
396*b077aed3SPierre ProncheryThe provider_get_capabilities() function should call the callback I<cb> passing
397*b077aed3SPierre Proncheryit a set of L<OSSL_PARAM(3)>s and the caller supplied argument I<arg>. The
398*b077aed3SPierre ProncheryL<OSSL_PARAM(3)>s should provide details about the capability with the name given
399*b077aed3SPierre Proncheryin the I<capability> argument relevant for the provider context I<provctx>. If a
400*b077aed3SPierre Proncheryprovider supports multiple capabilities with the given name then it may call the
401*b077aed3SPierre Proncherycallback multiple times (one for each capability). Capabilities can be useful for
402*b077aed3SPierre Proncherydescribing the services that a provider can offer. For further details see the
403*b077aed3SPierre ProncheryL</CAPABILITIES> section below. It should return 1 on success or 0 on error.
404*b077aed3SPierre Pronchery
405*b077aed3SPierre ProncheryThe provider_self_test() function should perform known answer tests on a subset
406*b077aed3SPierre Proncheryof the algorithms that it uses, and may also verify the integrity of the
407*b077aed3SPierre Proncheryprovider module. It should return 1 on success or 0 on error. It will return 1
408*b077aed3SPierre Proncheryif this function is not used.
409*b077aed3SPierre Pronchery
410*b077aed3SPierre ProncheryNone of these functions are mandatory, but a provider is fairly
411*b077aed3SPierre Proncheryuseless without at least provider_query_operation(), and
412*b077aed3SPierre Proncheryprovider_gettable_params() is fairly useless if not accompanied by
413*b077aed3SPierre Proncheryprovider_get_params().
414*b077aed3SPierre Pronchery
415*b077aed3SPierre Pronchery=head2 Provider parameters
416*b077aed3SPierre Pronchery
417*b077aed3SPierre Proncheryprovider_get_params() can return the following provider parameters to the core:
418*b077aed3SPierre Pronchery
419*b077aed3SPierre Pronchery=over 4
420*b077aed3SPierre Pronchery
421*b077aed3SPierre Pronchery=item "name" (B<OSSL_PROV_PARAM_NAME>) <UTF8 ptr>
422*b077aed3SPierre Pronchery
423*b077aed3SPierre ProncheryThis points to a string that should give a unique name for the provider.
424*b077aed3SPierre Pronchery
425*b077aed3SPierre Pronchery=item "version" (B<OSSL_PROV_PARAM_VERSION>) <UTF8 ptr>
426*b077aed3SPierre Pronchery
427*b077aed3SPierre ProncheryThis points to a string that is a version number associated with this provider.
428*b077aed3SPierre ProncheryOpenSSL in-built providers use OPENSSL_VERSION_STR, but this may be different
429*b077aed3SPierre Proncheryfor any third party provider. This string is for informational purposes only.
430*b077aed3SPierre Pronchery
431*b077aed3SPierre Pronchery=item "buildinfo" (B<OSSL_PROV_PARAM_BUILDINFO>) <UTF8 ptr>
432*b077aed3SPierre Pronchery
433*b077aed3SPierre ProncheryThis points to a string that is a build information associated with this provider.
434*b077aed3SPierre ProncheryOpenSSL in-built providers use OPENSSL_FULL_VERSION_STR, but this may be
435*b077aed3SPierre Proncherydifferent for any third party provider.
436*b077aed3SPierre Pronchery
437*b077aed3SPierre Pronchery=item "status" (B<OSSL_PROV_PARAM_STATUS>) <unsigned integer>
438*b077aed3SPierre Pronchery
439*b077aed3SPierre ProncheryThis returns 0 if the provider has entered an error state, otherwise it returns
440*b077aed3SPierre Pronchery1.
441*b077aed3SPierre Pronchery
442*b077aed3SPierre Pronchery=back
443*b077aed3SPierre Pronchery
444*b077aed3SPierre Proncheryprovider_gettable_params() should return the above parameters.
445*b077aed3SPierre Pronchery
446*b077aed3SPierre Pronchery
447*b077aed3SPierre Pronchery=head2 Core parameters
448*b077aed3SPierre Pronchery
449*b077aed3SPierre Proncherycore_get_params() can retrieve the following core parameters for each provider:
450*b077aed3SPierre Pronchery
451*b077aed3SPierre Pronchery=over 4
452*b077aed3SPierre Pronchery
453*b077aed3SPierre Pronchery=item "openssl-version" (B<OSSL_PROV_PARAM_CORE_VERSION>) <UTF8 string ptr>
454*b077aed3SPierre Pronchery
455*b077aed3SPierre ProncheryThis points to the OpenSSL libraries' full version string, i.e. the string
456*b077aed3SPierre Proncheryexpanded from the macro B<OPENSSL_VERSION_STR>.
457*b077aed3SPierre Pronchery
458*b077aed3SPierre Pronchery=item "provider-name" (B<OSSL_PROV_PARAM_CORE_PROV_NAME>) <UTF8 string ptr>
459*b077aed3SPierre Pronchery
460*b077aed3SPierre ProncheryThis points to the OpenSSL libraries' idea of what the calling provider is named.
461*b077aed3SPierre Pronchery
462*b077aed3SPierre Pronchery=item "module-filename" (B<OSSL_PROV_PARAM_CORE_MODULE_FILENAME>) <UTF8 string ptr>
463*b077aed3SPierre Pronchery
464*b077aed3SPierre ProncheryThis points to a string containing the full filename of the providers
465*b077aed3SPierre Proncherymodule file.
466*b077aed3SPierre Pronchery
467*b077aed3SPierre Pronchery=back
468*b077aed3SPierre Pronchery
469*b077aed3SPierre ProncheryAdditionally, provider specific configuration parameters from the
470*b077aed3SPierre Proncheryconfig file are available, in dotted name form.
471*b077aed3SPierre ProncheryThe dotted name form is a concatenation of section names and final
472*b077aed3SPierre Proncheryconfig command name separated by periods.
473*b077aed3SPierre Pronchery
474*b077aed3SPierre ProncheryFor example, let's say we have the following config example:
475*b077aed3SPierre Pronchery
476*b077aed3SPierre Pronchery config_diagnostics = 1
477*b077aed3SPierre Pronchery openssl_conf = openssl_init
478*b077aed3SPierre Pronchery
479*b077aed3SPierre Pronchery [openssl_init]
480*b077aed3SPierre Pronchery providers = providers_sect
481*b077aed3SPierre Pronchery
482*b077aed3SPierre Pronchery [providers_sect]
483*b077aed3SPierre Pronchery foo = foo_sect
484*b077aed3SPierre Pronchery
485*b077aed3SPierre Pronchery [foo_sect]
486*b077aed3SPierre Pronchery activate = 1
487*b077aed3SPierre Pronchery data1 = 2
488*b077aed3SPierre Pronchery data2 = str
489*b077aed3SPierre Pronchery more = foo_more
490*b077aed3SPierre Pronchery
491*b077aed3SPierre Pronchery [foo_more]
492*b077aed3SPierre Pronchery data3 = foo,bar
493*b077aed3SPierre Pronchery
494*b077aed3SPierre ProncheryThe provider will have these additional parameters available:
495*b077aed3SPierre Pronchery
496*b077aed3SPierre Pronchery=over 4
497*b077aed3SPierre Pronchery
498*b077aed3SPierre Pronchery=item "activate"
499*b077aed3SPierre Pronchery
500*b077aed3SPierre Proncherypointing at the string "1"
501*b077aed3SPierre Pronchery
502*b077aed3SPierre Pronchery=item "data1"
503*b077aed3SPierre Pronchery
504*b077aed3SPierre Proncherypointing at the string "2"
505*b077aed3SPierre Pronchery
506*b077aed3SPierre Pronchery=item "data2"
507*b077aed3SPierre Pronchery
508*b077aed3SPierre Proncherypointing at the string "str"
509*b077aed3SPierre Pronchery
510*b077aed3SPierre Pronchery=item "more.data3"
511*b077aed3SPierre Pronchery
512*b077aed3SPierre Proncherypointing at the string "foo,bar"
513*b077aed3SPierre Pronchery
514*b077aed3SPierre Pronchery=back
515*b077aed3SPierre Pronchery
516*b077aed3SPierre ProncheryFor more information on handling parameters, see L<OSSL_PARAM(3)> as
517*b077aed3SPierre ProncheryL<OSSL_PARAM_int(3)>.
518*b077aed3SPierre Pronchery
519*b077aed3SPierre Pronchery=head1 CAPABILITIES
520*b077aed3SPierre Pronchery
521*b077aed3SPierre ProncheryCapabilities describe some of the services that a provider can offer.
522*b077aed3SPierre ProncheryApplications can query the capabilities to discover those services.
523*b077aed3SPierre Pronchery
524*b077aed3SPierre Pronchery=head3 "TLS-GROUP" Capability
525*b077aed3SPierre Pronchery
526*b077aed3SPierre ProncheryThe "TLS-GROUP" capability can be queried by libssl to discover the list of
527*b077aed3SPierre ProncheryTLS groups that a provider can support. Each group supported can be used for
528*b077aed3SPierre ProncheryI<key exchange> (KEX) or I<key encapsulation method> (KEM) during a TLS
529*b077aed3SPierre Proncheryhandshake.
530*b077aed3SPierre ProncheryTLS clients can advertise the list of TLS groups they support in the
531*b077aed3SPierre Proncherysupported_groups extension, and TLS servers can select a group from the offered
532*b077aed3SPierre Proncherylist that they also support. In this way a provider can add to the list of
533*b077aed3SPierre Proncherygroups that libssl already supports with additional ones.
534*b077aed3SPierre Pronchery
535*b077aed3SPierre ProncheryEach TLS group that a provider supports should be described via the callback
536*b077aed3SPierre Proncherypassed in through the provider_get_capabilities function. Each group should have
537*b077aed3SPierre Proncherythe following details supplied (all are mandatory, except
538*b077aed3SPierre ProncheryB<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>):
539*b077aed3SPierre Pronchery
540*b077aed3SPierre Pronchery=over 4
541*b077aed3SPierre Pronchery
542*b077aed3SPierre Pronchery=item "tls-group-name" (B<OSSL_CAPABILITY_TLS_GROUP_NAME>) <UTF8 string>
543*b077aed3SPierre Pronchery
544*b077aed3SPierre ProncheryThe name of the group as given in the IANA TLS Supported Groups registry
545*b077aed3SPierre ProncheryL<https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.
546*b077aed3SPierre Pronchery
547*b077aed3SPierre Pronchery=item "tls-group-name-internal" (B<OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL>) <UTF8 string>
548*b077aed3SPierre Pronchery
549*b077aed3SPierre ProncheryThe name of the group as known by the provider. This could be the same as the
550*b077aed3SPierre Pronchery"tls-group-name", but does not have to be.
551*b077aed3SPierre Pronchery
552*b077aed3SPierre Pronchery=item "tls-group-id" (B<OSSL_CAPABILITY_TLS_GROUP_ID>) <unsigned integer>
553*b077aed3SPierre Pronchery
554*b077aed3SPierre ProncheryThe TLS group id value as given in the IANA TLS Supported Groups registry.
555*b077aed3SPierre Pronchery
556*b077aed3SPierre Pronchery=item "tls-group-alg" (B<OSSL_CAPABILITY_TLS_GROUP_ALG>) <UTF8 string>
557*b077aed3SPierre Pronchery
558*b077aed3SPierre ProncheryThe name of a Key Management algorithm that the provider offers and that should
559*b077aed3SPierre Proncherybe used with this group. Keys created should be able to support I<key exchange>
560*b077aed3SPierre Proncheryor I<key encapsulation method> (KEM), as implied by the optional
561*b077aed3SPierre ProncheryB<OSSL_CAPABILITY_TLS_GROUP_IS_KEM> flag.
562*b077aed3SPierre ProncheryThe algorithm must support key and parameter generation as well as the
563*b077aed3SPierre Proncherykey/parameter generation parameter, B<OSSL_PKEY_PARAM_GROUP_NAME>. The group
564*b077aed3SPierre Proncheryname given via "tls-group-name-internal" above will be passed via
565*b077aed3SPierre ProncheryB<OSSL_PKEY_PARAM_GROUP_NAME> when libssl wishes to generate keys/parameters.
566*b077aed3SPierre Pronchery
567*b077aed3SPierre Pronchery=item "tls-group-sec-bits" (B<OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS>) <unsigned integer>
568*b077aed3SPierre Pronchery
569*b077aed3SPierre ProncheryThe number of bits of security offered by keys in this group. The number of bits
570*b077aed3SPierre Proncheryshould be comparable with the ones given in table 2 and 3 of the NIST SP800-57
571*b077aed3SPierre Proncherydocument.
572*b077aed3SPierre Pronchery
573*b077aed3SPierre Pronchery=item "tls-group-is-kem" (B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>) <unsigned integer>
574*b077aed3SPierre Pronchery
575*b077aed3SPierre ProncheryBoolean flag to describe if the group should be used in I<key exchange> (KEX)
576*b077aed3SPierre Proncherymode (0, default) or in I<key encapsulation method> (KEM) mode (1).
577*b077aed3SPierre Pronchery
578*b077aed3SPierre ProncheryThis parameter is optional: if not specified, KEX mode is assumed as the default
579*b077aed3SPierre Proncherymode for the group.
580*b077aed3SPierre Pronchery
581*b077aed3SPierre ProncheryIn KEX mode, in a typical Diffie-Hellman fashion, both sides execute I<keygen>
582*b077aed3SPierre Proncherythen I<derive> against the peer public key. To operate in KEX mode, the group
583*b077aed3SPierre Proncheryimplementation must support the provider functions as described in
584*b077aed3SPierre ProncheryL<provider-keyexch(7)>.
585*b077aed3SPierre Pronchery
586*b077aed3SPierre ProncheryIn KEM mode, the client executes I<keygen> and sends its public key, the server
587*b077aed3SPierre Proncheryexecutes I<encapsulate> using the client's public key and sends back the
588*b077aed3SPierre Proncheryresulting I<ciphertext>, finally the client executes I<decapsulate> to retrieve
589*b077aed3SPierre Proncherythe same I<shared secret> generated by the server's I<encapsulate>. To operate
590*b077aed3SPierre Proncheryin KEM mode, the group implementation must support the provider functions as
591*b077aed3SPierre Proncherydescribed in L<provider-kem(7)>.
592*b077aed3SPierre Pronchery
593*b077aed3SPierre ProncheryBoth in KEX and KEM mode, the resulting I<shared secret> is then used according
594*b077aed3SPierre Proncheryto the protocol specification.
595*b077aed3SPierre Pronchery
596*b077aed3SPierre Pronchery=item "tls-min-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MIN_TLS>) <integer>
597*b077aed3SPierre Pronchery
598*b077aed3SPierre Pronchery=item "tls-max-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MAX_TLS>) <integer>
599*b077aed3SPierre Pronchery
600*b077aed3SPierre Pronchery=item "tls-min-dtls" (B<OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS>) <integer>
601*b077aed3SPierre Pronchery
602*b077aed3SPierre Pronchery=item "tls-max-dtls" (B<OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS>) <integer>
603*b077aed3SPierre Pronchery
604*b077aed3SPierre ProncheryThese parameters can be used to describe the minimum and maximum TLS and DTLS
605*b077aed3SPierre Proncheryversions supported by the group. The values equate to the on-the-wire encoding
606*b077aed3SPierre Proncheryof the various TLS versions. For example TLSv1.3 is 0x0304 (772 decimal), and
607*b077aed3SPierre ProncheryTLSv1.2 is 0x0303 (771 decimal). A 0 indicates that there is no defined minimum
608*b077aed3SPierre Proncheryor maximum. A -1 indicates that the group should not be used in that protocol.
609*b077aed3SPierre Pronchery
610*b077aed3SPierre Pronchery=back
611*b077aed3SPierre Pronchery
612*b077aed3SPierre Pronchery=head1 EXAMPLES
613*b077aed3SPierre Pronchery
614*b077aed3SPierre ProncheryThis is an example of a simple provider made available as a
615*b077aed3SPierre Proncherydynamically loadable module.
616*b077aed3SPierre ProncheryIt implements the fictitious algorithm C<FOO> for the fictitious
617*b077aed3SPierre Proncheryoperation C<BAR>.
618*b077aed3SPierre Pronchery
619*b077aed3SPierre Pronchery #include <malloc.h>
620*b077aed3SPierre Pronchery #include <openssl/core.h>
621*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
622*b077aed3SPierre Pronchery
623*b077aed3SPierre Pronchery /* Errors used in this provider */
624*b077aed3SPierre Pronchery #define E_MALLOC       1
625*b077aed3SPierre Pronchery
626*b077aed3SPierre Pronchery static const OSSL_ITEM reasons[] = {
627*b077aed3SPierre Pronchery     { E_MALLOC, "memory allocation failure" }.
628*b077aed3SPierre Pronchery     { 0, NULL } /* Termination */
629*b077aed3SPierre Pronchery };
630*b077aed3SPierre Pronchery
631*b077aed3SPierre Pronchery /*
632*b077aed3SPierre Pronchery  * To ensure we get the function signature right, forward declare
633*b077aed3SPierre Pronchery  * them using function types provided by openssl/core_dispatch.h
634*b077aed3SPierre Pronchery  */
635*b077aed3SPierre Pronchery OSSL_FUNC_bar_newctx_fn foo_newctx;
636*b077aed3SPierre Pronchery OSSL_FUNC_bar_freectx_fn foo_freectx;
637*b077aed3SPierre Pronchery OSSL_FUNC_bar_init_fn foo_init;
638*b077aed3SPierre Pronchery OSSL_FUNC_bar_update_fn foo_update;
639*b077aed3SPierre Pronchery OSSL_FUNC_bar_final_fn foo_final;
640*b077aed3SPierre Pronchery
641*b077aed3SPierre Pronchery OSSL_FUNC_provider_query_operation_fn p_query;
642*b077aed3SPierre Pronchery OSSL_FUNC_provider_get_reason_strings_fn p_reasons;
643*b077aed3SPierre Pronchery OSSL_FUNC_provider_teardown_fn p_teardown;
644*b077aed3SPierre Pronchery
645*b077aed3SPierre Pronchery OSSL_provider_init_fn OSSL_provider_init;
646*b077aed3SPierre Pronchery
647*b077aed3SPierre Pronchery OSSL_FUNC_core_put_error *c_put_error = NULL;
648*b077aed3SPierre Pronchery
649*b077aed3SPierre Pronchery /* Provider context */
650*b077aed3SPierre Pronchery struct prov_ctx_st {
651*b077aed3SPierre Pronchery     OSSL_CORE_HANDLE *handle;
652*b077aed3SPierre Pronchery }
653*b077aed3SPierre Pronchery
654*b077aed3SPierre Pronchery /* operation context for the algorithm FOO */
655*b077aed3SPierre Pronchery struct foo_ctx_st {
656*b077aed3SPierre Pronchery     struct prov_ctx_st *provctx;
657*b077aed3SPierre Pronchery     int b;
658*b077aed3SPierre Pronchery };
659*b077aed3SPierre Pronchery
660*b077aed3SPierre Pronchery static void *foo_newctx(void *provctx)
661*b077aed3SPierre Pronchery {
662*b077aed3SPierre Pronchery     struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx));
663*b077aed3SPierre Pronchery
664*b077aed3SPierre Pronchery     if (fooctx != NULL)
665*b077aed3SPierre Pronchery         fooctx->provctx = provctx;
666*b077aed3SPierre Pronchery     else
667*b077aed3SPierre Pronchery         c_put_error(provctx->handle, E_MALLOC, __FILE__, __LINE__);
668*b077aed3SPierre Pronchery     return fooctx;
669*b077aed3SPierre Pronchery }
670*b077aed3SPierre Pronchery
671*b077aed3SPierre Pronchery static void foo_freectx(void *fooctx)
672*b077aed3SPierre Pronchery {
673*b077aed3SPierre Pronchery     free(fooctx);
674*b077aed3SPierre Pronchery }
675*b077aed3SPierre Pronchery
676*b077aed3SPierre Pronchery static int foo_init(void *vfooctx)
677*b077aed3SPierre Pronchery {
678*b077aed3SPierre Pronchery     struct foo_ctx_st *fooctx = vfooctx;
679*b077aed3SPierre Pronchery
680*b077aed3SPierre Pronchery     fooctx->b = 0x33;
681*b077aed3SPierre Pronchery }
682*b077aed3SPierre Pronchery
683*b077aed3SPierre Pronchery static int foo_update(void *vfooctx, unsigned char *in, size_t inl)
684*b077aed3SPierre Pronchery {
685*b077aed3SPierre Pronchery     struct foo_ctx_st *fooctx = vfooctx;
686*b077aed3SPierre Pronchery
687*b077aed3SPierre Pronchery     /* did you expect something serious? */
688*b077aed3SPierre Pronchery     if (inl == 0)
689*b077aed3SPierre Pronchery         return 1;
690*b077aed3SPierre Pronchery     for (; inl-- > 0; in++)
691*b077aed3SPierre Pronchery         *in ^= fooctx->b;
692*b077aed3SPierre Pronchery     return 1;
693*b077aed3SPierre Pronchery }
694*b077aed3SPierre Pronchery
695*b077aed3SPierre Pronchery static int foo_final(void *vfooctx)
696*b077aed3SPierre Pronchery {
697*b077aed3SPierre Pronchery     struct foo_ctx_st *fooctx = vfooctx;
698*b077aed3SPierre Pronchery
699*b077aed3SPierre Pronchery     fooctx->b = 0x66;
700*b077aed3SPierre Pronchery }
701*b077aed3SPierre Pronchery
702*b077aed3SPierre Pronchery static const OSSL_DISPATCH foo_fns[] = {
703*b077aed3SPierre Pronchery     { OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx },
704*b077aed3SPierre Pronchery     { OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx },
705*b077aed3SPierre Pronchery     { OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init },
706*b077aed3SPierre Pronchery     { OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update },
707*b077aed3SPierre Pronchery     { OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final },
708*b077aed3SPierre Pronchery     { 0, NULL }
709*b077aed3SPierre Pronchery };
710*b077aed3SPierre Pronchery
711*b077aed3SPierre Pronchery static const OSSL_ALGORITHM bars[] = {
712*b077aed3SPierre Pronchery     { "FOO", "provider=chumbawamba", foo_fns },
713*b077aed3SPierre Pronchery     { NULL, NULL, NULL }
714*b077aed3SPierre Pronchery };
715*b077aed3SPierre Pronchery
716*b077aed3SPierre Pronchery static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id,
717*b077aed3SPierre Pronchery                                      int *no_store)
718*b077aed3SPierre Pronchery {
719*b077aed3SPierre Pronchery     switch (operation_id) {
720*b077aed3SPierre Pronchery     case OSSL_OP_BAR:
721*b077aed3SPierre Pronchery         return bars;
722*b077aed3SPierre Pronchery     }
723*b077aed3SPierre Pronchery     return NULL;
724*b077aed3SPierre Pronchery }
725*b077aed3SPierre Pronchery
726*b077aed3SPierre Pronchery static const OSSL_ITEM *p_reasons(void *provctx)
727*b077aed3SPierre Pronchery {
728*b077aed3SPierre Pronchery     return reasons;
729*b077aed3SPierre Pronchery }
730*b077aed3SPierre Pronchery
731*b077aed3SPierre Pronchery static void p_teardown(void *provctx)
732*b077aed3SPierre Pronchery {
733*b077aed3SPierre Pronchery     free(provctx);
734*b077aed3SPierre Pronchery }
735*b077aed3SPierre Pronchery
736*b077aed3SPierre Pronchery static const OSSL_DISPATCH prov_fns[] = {
737*b077aed3SPierre Pronchery     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown },
738*b077aed3SPierre Pronchery     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query },
739*b077aed3SPierre Pronchery     { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons },
740*b077aed3SPierre Pronchery     { 0, NULL }
741*b077aed3SPierre Pronchery };
742*b077aed3SPierre Pronchery
743*b077aed3SPierre Pronchery int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
744*b077aed3SPierre Pronchery                        const OSSL_DISPATCH *in,
745*b077aed3SPierre Pronchery                        const OSSL_DISPATCH **out,
746*b077aed3SPierre Pronchery                        void **provctx)
747*b077aed3SPierre Pronchery {
748*b077aed3SPierre Pronchery     struct prov_ctx_st *pctx = NULL;
749*b077aed3SPierre Pronchery
750*b077aed3SPierre Pronchery     for (; in->function_id != 0; in++)
751*b077aed3SPierre Pronchery         switch (in->function_id) {
752*b077aed3SPierre Pronchery         case OSSL_FUNC_CORE_PUT_ERROR:
753*b077aed3SPierre Pronchery             c_put_error = OSSL_FUNC_core_put_error(in);
754*b077aed3SPierre Pronchery             break;
755*b077aed3SPierre Pronchery         }
756*b077aed3SPierre Pronchery
757*b077aed3SPierre Pronchery     *out = prov_fns;
758*b077aed3SPierre Pronchery
759*b077aed3SPierre Pronchery     if ((pctx = malloc(sizeof(*pctx))) == NULL) {
760*b077aed3SPierre Pronchery         /*
761*b077aed3SPierre Pronchery          * ALEA IACTA EST, if the core retrieves the reason table
762*b077aed3SPierre Pronchery          * regardless, that string will be displayed, otherwise not.
763*b077aed3SPierre Pronchery          */
764*b077aed3SPierre Pronchery         c_put_error(handle, E_MALLOC, __FILE__, __LINE__);
765*b077aed3SPierre Pronchery         return 0;
766*b077aed3SPierre Pronchery     }
767*b077aed3SPierre Pronchery     pctx->handle = handle;
768*b077aed3SPierre Pronchery     return 1;
769*b077aed3SPierre Pronchery }
770*b077aed3SPierre Pronchery
771*b077aed3SPierre ProncheryThis relies on a few things existing in F<openssl/core_dispatch.h>:
772*b077aed3SPierre Pronchery
773*b077aed3SPierre Pronchery #define OSSL_OP_BAR            4711
774*b077aed3SPierre Pronchery
775*b077aed3SPierre Pronchery #define OSSL_FUNC_BAR_NEWCTX      1
776*b077aed3SPierre Pronchery typedef void *(OSSL_FUNC_bar_newctx_fn)(void *provctx);
777*b077aed3SPierre Pronchery static ossl_inline OSSL_FUNC_bar_newctx(const OSSL_DISPATCH *opf)
778*b077aed3SPierre Pronchery { return (OSSL_FUNC_bar_newctx_fn *)opf->function; }
779*b077aed3SPierre Pronchery
780*b077aed3SPierre Pronchery #define OSSL_FUNC_BAR_FREECTX     2
781*b077aed3SPierre Pronchery typedef void (OSSL_FUNC_bar_freectx_fn)(void *ctx);
782*b077aed3SPierre Pronchery static ossl_inline OSSL_FUNC_bar_freectx(const OSSL_DISPATCH *opf)
783*b077aed3SPierre Pronchery { return (OSSL_FUNC_bar_freectx_fn *)opf->function; }
784*b077aed3SPierre Pronchery
785*b077aed3SPierre Pronchery #define OSSL_FUNC_BAR_INIT        3
786*b077aed3SPierre Pronchery typedef void *(OSSL_FUNC_bar_init_fn)(void *ctx);
787*b077aed3SPierre Pronchery static ossl_inline OSSL_FUNC_bar_init(const OSSL_DISPATCH *opf)
788*b077aed3SPierre Pronchery { return (OSSL_FUNC_bar_init_fn *)opf->function; }
789*b077aed3SPierre Pronchery
790*b077aed3SPierre Pronchery #define OSSL_FUNC_BAR_UPDATE      4
791*b077aed3SPierre Pronchery typedef void *(OSSL_FUNC_bar_update_fn)(void *ctx,
792*b077aed3SPierre Pronchery                                       unsigned char *in, size_t inl);
793*b077aed3SPierre Pronchery static ossl_inline OSSL_FUNC_bar_update(const OSSL_DISPATCH *opf)
794*b077aed3SPierre Pronchery { return (OSSL_FUNC_bar_update_fn *)opf->function; }
795*b077aed3SPierre Pronchery
796*b077aed3SPierre Pronchery #define OSSL_FUNC_BAR_FINAL       5
797*b077aed3SPierre Pronchery typedef void *(OSSL_FUNC_bar_final_fn)(void *ctx);
798*b077aed3SPierre Pronchery static ossl_inline OSSL_FUNC_bar_final(const OSSL_DISPATCH *opf)
799*b077aed3SPierre Pronchery { return (OSSL_FUNC_bar_final_fn *)opf->function; }
800*b077aed3SPierre Pronchery
801*b077aed3SPierre Pronchery=head1 SEE ALSO
802*b077aed3SPierre Pronchery
803*b077aed3SPierre ProncheryL<provider(7)>
804*b077aed3SPierre Pronchery
805*b077aed3SPierre Pronchery=head1 HISTORY
806*b077aed3SPierre Pronchery
807*b077aed3SPierre ProncheryThe concept of providers and everything surrounding them was
808*b077aed3SPierre Proncheryintroduced in OpenSSL 3.0.
809*b077aed3SPierre Pronchery
810*b077aed3SPierre Pronchery=head1 COPYRIGHT
811*b077aed3SPierre Pronchery
812*b077aed3SPierre ProncheryCopyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
813*b077aed3SPierre Pronchery
814*b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
815*b077aed3SPierre Proncherythis file except in compliance with the License.  You can obtain a copy
816*b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at
817*b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>.
818*b077aed3SPierre Pronchery
819*b077aed3SPierre Pronchery=cut
820