123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694 |
- =pod
- =head1 NAME
- provider-base
- - The basic OpenSSL library E<lt>-E<gt> provider functions
- =head1 SYNOPSIS
- #include <openssl/core_dispatch.h>
- /*
- * None of these are actual functions, but are displayed like this for
- * the function signatures for functions that are offered as function
- * pointers in OSSL_DISPATCH arrays.
- */
- /* Functions offered by libcrypto to the providers */
- const OSSL_ITEM *core_gettable_params(const OSSL_CORE_HANDLE *handle);
- int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]);
- int core_thread_start(const OSSL_CORE_HANDLE *handle,
- OSSL_thread_stop_handler_fn handfn);
- OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle);
- void core_new_error(const OSSL_CORE_HANDLE *handle);
- void core_set_error_debug(const OSSL_CORE_HANDLE *handle,
- const char *file, int line, const char *func);
- void core_vset_error(const OSSL_CORE_HANDLE *handle,
- uint32_t reason, const char *fmt, va_list args);
- /*
- * Some OpenSSL functionality is directly offered to providers via
- * dispatch
- */
- void *CRYPTO_malloc(size_t num, const char *file, int line);
- void *CRYPTO_zalloc(size_t num, const char *file, int line);
- void *CRYPTO_memdup(const void *str, size_t siz,
- const char *file, int line);
- char *CRYPTO_strdup(const char *str, const char *file, int line);
- char *CRYPTO_strndup(const char *str, size_t s,
- const char *file, int line);
- void CRYPTO_free(void *ptr, const char *file, int line);
- void CRYPTO_clear_free(void *ptr, size_t num,
- const char *file, int line);
- void *CRYPTO_realloc(void *addr, size_t num,
- const char *file, int line);
- void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
- const char *file, int line);
- void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
- void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
- void CRYPTO_secure_free(void *ptr, const char *file, int line);
- void CRYPTO_secure_clear_free(void *ptr, size_t num,
- const char *file, int line);
- int CRYPTO_secure_allocated(const void *ptr);
- void OPENSSL_cleanse(void *ptr, size_t len);
- OSSL_CORE_BIO * BIO_new_file(const char *filename, const char *mode)
- OSSL_CORE_BIO * BIO_new_membuf(const void *buf, int len)
- int BIO_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
- size_t *bytes_read))
- int BIO_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
- size_t *written)
- int BIO_free(OSSL_CORE_BIO *bio))
- int BIO_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list args)
- int BIO_vsnprintf(char *buf, size_t n, const char *fmt, va_list args)
- void self_test_cb(OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, void **cbarg)
- size_t get_entropy(const OSSL_CORE_HANDLE *handle,
- unsigned char **pout, int entropy,
- size_t min_len, size_t max_len)
- void cleanup_entropy(const OSSL_CORE_HANDLE *handle,
- unsigned char *buf, size_t len)
- size_t get_nonce(const OSSL_CORE_HANDLE *handle,
- unsigned char **pout, size_t min_len, size_t max_len,
- const void *salt, size_t salt_len)
- void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
- unsigned char *buf, size_t len)
- /* Functions offered by the provider to libcrypto */
- void provider_teardown(void *provctx);
- const OSSL_ITEM *provider_gettable_params(void *provctx);
- int provider_get_params(void *provctx, OSSL_PARAM params[]);
- const OSSL_ALGORITHM *provider_query_operation(void *provctx,
- int operation_id,
- const int *no_store);
- const OSSL_ITEM *provider_get_reason_strings(void *provctx);
- int provider_get_capabilities(void *provctx, const char *capability,
- OSSL_CALLBACK *cb, void *arg);
- =head1 DESCRIPTION
- All "functions" mentioned here are passed as function pointers between
- F<libcrypto> and the provider in B<OSSL_DISPATCH> arrays, in the call
- of the provider initialization function. See L<provider(7)/Provider>
- for a description of the initialization function.
- All these "functions" have a corresponding function type definition
- named B<OSSL_{name}_fn>, and a helper function to retrieve the
- function pointer from a B<OSSL_DISPATCH> element named
- B<OSSL_FUNC_{name}>.
- For example, the "function" core_gettable_params() has these:
- typedef OSSL_PARAM *
- (OSSL_FUNC_core_gettable_params_fn)(const OSSL_CORE_HANDLE *handle);
- static ossl_inline OSSL_NAME_core_gettable_params_fn
- OSSL_FUNC_core_gettable_params(const OSSL_DISPATCH *opf);
- B<OSSL_DISPATCH> arrays are indexed by numbers that are provided as
- macros in L<openssl-core_dispatch.h(7)>, as follows:
- For I<in> (the B<OSSL_DISPATCH> array passed from F<libcrypto> to the
- provider):
- core_gettable_params OSSL_FUNC_CORE_GETTABLE_PARAMS
- core_get_params OSSL_FUNC_CORE_GET_PARAMS
- core_thread_start OSSL_FUNC_CORE_THREAD_START
- core_get_libctx OSSL_FUNC_CORE_GET_LIBCTX
- core_new_error OSSL_FUNC_CORE_NEW_ERROR
- core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG
- core_set_error OSSL_FUNC_CORE_SET_ERROR
- CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC
- CRYPTO_zalloc OSSL_FUNC_CRYPTO_ZALLOC
- CRYPTO_memdup OSSL_FUNC_CRYPTO_MEMDUP
- CRYPTO_strdup OSSL_FUNC_CRYPTO_STRDUP
- CRYPTO_strndup OSSL_FUNC_CRYPTO_STRNDUP
- CRYPTO_free OSSL_FUNC_CRYPTO_FREE
- CRYPTO_clear_free OSSL_FUNC_CRYPTO_CLEAR_FREE
- CRYPTO_realloc OSSL_FUNC_CRYPTO_REALLOC
- CRYPTO_clear_realloc OSSL_FUNC_CRYPTO_CLEAR_REALLOC
- CRYPTO_secure_malloc OSSL_FUNC_CRYPTO_SECURE_MALLOC
- CRYPTO_secure_zalloc OSSL_FUNC_CRYPTO_SECURE_ZALLOC
- CRYPTO_secure_free OSSL_FUNC_CRYPTO_SECURE_FREE
- CRYPTO_secure_clear_free OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE
- CRYPTO_secure_allocated OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
- BIO_new_file OSSL_FUNC_BIO_NEW_FILE
- BIO_new_mem_buf OSSL_FUNC_BIO_NEW_MEMBUF
- BIO_read_ex OSSL_FUNC_BIO_READ_EX
- BIO_free OSSL_FUNC_BIO_FREE
- BIO_vprintf OSSL_FUNC_BIO_VPRINTF
- OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE
- OSSL_SELF_TEST_set_callback OSSL_FUNC_SELF_TEST_CB
- ossl_rand_get_entropy OSSL_FUNC_GET_ENTROPY
- ossl_rand_cleanup_entropy OSSL_FUNC_CLEANUP_ENTROPY
- ossl_rand_get_nonce OSSL_FUNC_GET_NONCE
- ossl_rand_cleanup_nonce OSSL_FUNC_CLEANUP_NONCE
- For I<*out> (the B<OSSL_DISPATCH> array passed from the provider to
- F<libcrypto>):
- provider_teardown OSSL_FUNC_PROVIDER_TEARDOWN
- provider_gettable_params OSSL_FUNC_PROVIDER_GETTABLE_PARAMS
- provider_get_params OSSL_FUNC_PROVIDER_GET_PARAMS
- provider_query_operation OSSL_FUNC_PROVIDER_QUERY_OPERATION
- provider_get_reason_strings OSSL_FUNC_PROVIDER_GET_REASON_STRINGS
- provider_get_capabilities OSSL_FUNC_PROVIDER_GET_CAPABILITIES
- provider_self_test OSSL_FUNC_PROVIDER_SELF_TEST
- =head2 Core functions
- core_gettable_params() returns a constant array of descriptor
- B<OSSL_PARAM>, for parameters that core_get_params() can handle.
- core_get_params() retrieves parameters from the core for the given I<handle>.
- See L</Core parameters> below for a description of currently known
- parameters.
- =for comment core_thread_start() TBA
- core_get_libctx() retrieves the library context in which the library
- object for the current provider is stored, accessible through the I<handle>.
- This may sometimes be useful if the provider wishes to store a
- reference to its context in the same library context.
- core_new_error(), core_set_error_debug() and core_set_error() are
- building blocks for reporting an error back to the core, with
- reference to the I<handle>.
- =over 4
- =item core_new_error()
- allocates a new thread specific error record.
- This corresponds to the OpenSSL function L<ERR_new(3)>.
- =item core_set_error_debug()
- sets debugging information in the current thread specific error
- record.
- The debugging information includes the name of the file I<file>, the
- line I<line> and the function name I<func> where the error occurred.
- This corresponds to the OpenSSL function L<ERR_set_debug(3)>.
- =item core_set_error()
- sets the I<reason> for the error, along with any addition data.
- The I<reason> is a number defined by the provider and used to index
- the reason strings table that's returned by
- provider_get_reason_strings().
- The additional data is given as a format string I<fmt> and a set of
- arguments I<args>, which are treated in the same manner as with
- BIO_vsnprintf().
- I<file> and I<line> may also be passed to indicate exactly where the
- error occurred or was reported.
- This corresponds to the OpenSSL function L<ERR_vset_error(3)>.
- =back
- CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_memdup(), CRYPTO_strdup(),
- CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(),
- CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(),
- CRYPTO_secure_zalloc(), CRYPTO_secure_free(),
- CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(),
- BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_free(),
- BIO_vprintf(), OPENSSL_cleanse(), and OPENSSL_hexstr2buf()
- correspond exactly to the public functions with the same name.
- As a matter of fact, the pointers in the B<OSSL_DISPATCH> array are
- direct pointers to those public functions. Note that the BIO functions take an
- B<OSSL_CORE_BIO> type rather than the standard B<BIO> type. This is to ensure
- that a provider does not mix BIOs from the core with BIOs used on the provider
- side (the two are not compatible).
- OSSL_SELF_TEST_set_callback() is used to set an optional callback that can be
- passed into a provider. This may be ignored by a provider.
- get_entropy() retrieves seeding material from the operating system.
- The seeding material will have at least I<entropy> bytes of randomness and the
- output will have at least I<min_len> and at most I<max_len> bytes.
- The buffer address is stored in I<*pout> and the buffer length is
- returned to the caller. On error, zero is returned.
- cleanup_entropy() is used to clean up and free the buffer returned by
- get_entropy(). The entropy pointer returned by get_entropy() is passed in
- B<buf> and its length in B<len>.
- get_nonce() retrieves a nonce using the passed I<salt> parameter
- of length I<salt_len> and operating system specific information.
- The I<salt> should contain uniquely identifying information and this is
- included, in an unspecified manner, as part of the output.
- The output is stored in a buffer which contrains at least I<min_len> and at
- most I<max_len> bytes. The buffer address is stored in I<*pout> and the
- buffer length returned to the caller. On error, zero is returned.
- cleanup_nonce() is used to clean up and free the buffer returned by
- get_nonce(). The nonce pointer returned by get_nonce() is passed in
- B<buf> and its length in B<len>.
- =head2 Provider functions
- provider_teardown() is called when a provider is shut down and removed
- from the core's provider store.
- It must free the passed I<provctx>.
- provider_gettable_params() should return a constant array of
- descriptor B<OSSL_PARAM>, for parameters that provider_get_params()
- can handle.
- provider_get_params() should process the B<OSSL_PARAM> array
- I<params>, setting the values of the parameters it understands.
- provider_query_operation() should return a constant B<OSSL_ALGORITHM>
- that corresponds to the given I<operation_id>.
- It should indicate if the core may store a reference to this array by
- setting I<*no_store> to 0 (core may store a reference) or 1 (core may
- not store a reference).
- provider_get_reason_strings() should return a constant B<OSSL_ITEM>
- array that provides reason strings for reason codes the provider may
- use when reporting errors using core_put_error().
- The provider_get_capabilities() function should call the callback I<cb> passing
- it a set of B<OSSL_PARAM>s and the caller supplied argument I<arg>. The
- B<OSSL_PARAM>s should provide details about the capability with the name given
- in the I<capability> argument relevant for the provider context I<provctx>. If a
- provider supports multiple capabilities with the given name then it may call the
- callback multiple times (one for each capability). Capabilities can be useful for
- describing the services that a provider can offer. For further details see the
- L</CAPABILITIES> section below. It should return 1 on success or 0 on error.
- The provider_self_test() function should perform known answer tests on a subset
- of the algorithms that it uses, and may also verify the integrity of the
- provider module. It should return 1 on success or 0 on error. It will return 1
- if this function is not used.
- None of these functions are mandatory, but a provider is fairly
- useless without at least provider_query_operation(), and
- provider_gettable_params() is fairly useless if not accompanied by
- provider_get_params().
- =head2 Provider parameters
- provider_get_params() can return the following provider parameters to the core:
- =over 4
- =item "name" (B<OSSL_PROV_PARAM_NAME>) <UTF8_ptr>
- This points to a string that should give a unique name for the provider.
- =item "version" (B<OSSL_PROV_PARAM_VERSION>) <UTF8_ptr>
- This points to a string that is a version number associated with this provider.
- OpenSSL in-built providers use OPENSSL_VERSION_STR, but this may be different
- for any third party provider. This string is for informational purposes only.
- =item "buildinfo" (B<OSSL_PROV_PARAM_BUILDINFO>) <UTF8_ptr>
- This points to a string that is a build information associated with this provider.
- OpenSSL in-built providers use OPENSSL_FULL_VERSION_STR, but this may be
- different for any third party provider.
- =item "status" (B<OSSL_PROV_PARAM_STATUS>) <unsigned integer>
- This returns 0 if the provider has entered an error state, otherwise it returns
- 1.
- =back
- provider_gettable_params() should return the above parameters.
- =head2 Core parameters
- core_get_params() can retrieve the following core parameters for each provider:
- =over 4
- =item "openssl-version" (B<OSSL_PROV_PARAM_CORE_VERSION>) <UTF8_ptr>
- This points to the OpenSSL libraries' full version string, i.e. the string
- expanded from the macro B<OPENSSL_VERSION_STR>.
- =item "provider-name" (B<OSSL_PROV_PARAM_CORE_PROV_NAME>) <UTF8_ptr>
- This points to the OpenSSL libraries' idea of what the calling provider is named.
- =item "module-filename" (B<OSSL_PROV_PARAM_CORE_MODULE_FILENAME>) <UTF8_ptr>
- This points to a string containing the full filename of the providers
- module file.
- =back
- Additionally, provider specific configuration parameters from the
- config file are available, in dotted name form.
- The dotted name form is a concatenation of section names and final
- config command name separated by periods.
- For example, let's say we have the following config example:
- openssl_conf = openssl_init
- [openssl_init]
- providers = providers_sect
- [providers_sect]
- foo = foo_sect
- [foo_sect]
- activate = 1
- data1 = 2
- data2 = str
- more = foo_more
- [foo_more]
- data3 = foo,bar
- The provider will have these additional parameters available:
- =over 4
- =item "activate"
- pointing at the string "1"
- =item "data1"
- pointing at the string "2"
- =item "data2"
- pointing at the string "str"
- =item "more.data3"
- pointing at the string "foo,bar"
- =back
- For more information on handling parameters, see L<OSSL_PARAM(3)> as
- L<OSSL_PARAM_int(3)>.
- =head1 CAPABILITIES
- Capabilities describe some of the services that a provider can offer.
- Applications can query the capabilities to discover those services.
- =head3 "TLS-GROUP" Capability
- The "TLS-GROUP" capability can be queried by libssl to discover the list of
- TLS groups that a provider can support. Each group supported can be used for
- I<key exchange> (KEX) or I<key encapsulation method> (KEM) during a TLS
- handshake.
- TLS clients can advertise the list of TLS groups they support in the
- supported_groups extension, and TLS servers can select a group from the offered
- list that they also support. In this way a provider can add to the list of
- groups that libssl already supports with additional ones.
- Each TLS group that a provider supports should be described via the callback
- passed in through the provider_get_capabilities function. Each group should have
- the following details supplied (all are mandatory, except
- B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>):
- =over 4
- =item "tls-group-name" (B<OSSL_CAPABILITY_TLS_GROUP_NAME>) <utf8 string>
- The name of the group as given in the IANA TLS Supported Groups registry
- L<https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.
- =item "tls-group-name-internal" (B<OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL>) <utf8 string>
- The name of the group as known by the provider. This could be the same as the
- "tls-group-name", but does not have to be.
- =item "tls-group-id" (B<OSSL_CAPABILITY_TLS_GROUP_ID>) <unsigned integer>
- The TLS group id value as given in the IANA TLS Supported Groups registry.
- =item "tls-group-alg" (B<OSSL_CAPABILITY_TLS_GROUP_ALG>) <utf8 string>
- The name of a Key Management algorithm that the provider offers and that should
- be used with this group. Keys created should be able to support I<key exchange>
- or I<key encapsulation method> (KEM), as implied by the optional
- B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM> flag.
- The algorithm must support key and parameter generation as well as the
- key/parameter generation parameter, B<OSSL_PKEY_PARAM_GROUP_NAME>. The group
- name given via "tls-group-name-internal" above will be passed via
- B<OSSL_PKEY_PARAM_GROUP_NAME> when libssl wishes to generate keys/parameters.
- =item "tls-group-sec-bits" (B<OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS>) <unsigned integer>
- The number of bits of security offered by keys in this group. The number of bits
- should be comparable with the ones given in table 2 and 3 of the NIST SP800-57
- document.
- =item "tls-group-is-kem" (B<OSSL_CAPABILITY_TLS_GROUP_IS_KEM>) <unsigned integer>
- Boolean flag to describe if the group should be used in I<key exchange> (KEX)
- mode (0, default) or in I<key encapsulation method> (KEM) mode (1).
- This parameter is optional: if not specified, KEX mode is assumed as the default
- mode for the group.
- In KEX mode, in a typical Diffie-Hellman fashion, both sides execute I<keygen>
- then I<derive> against the peer public key. To operate in KEX mode, the group
- implementation must support the provider functions as described in
- L<provider-keyexch(7)>.
- In KEM mode, the client executes I<keygen> and sends its public key, the server
- executes I<encapsulate> using the client's public key and sends back the
- resulting I<ciphertext>, finally the client executes I<decapsulate> to retrieve
- the same I<shared secret> generated by the server's I<encapsulate>. To operate
- in KEM mode, the group implementation must support the provider functions as
- described in L<provider-kem(7)>.
- Both in KEX and KEM mode, the resulting I<shared secret> is then used according
- to the protocol specification.
- =item "tls-min-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MIN_TLS>) <integer>
- =item "tls-max-tls" (B<OSSL_CAPABILITY_TLS_GROUP_MAX_TLS>) <integer>
- =item "tls-min-dtls" (B<OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS>) <integer>
- =item "tls-max-dtls" (B<OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS>) <integer>
- These parameters can be used to describe the minimum and maximum TLS and DTLS
- versions supported by the group. The values equate to the on-the-wire encoding
- of the various TLS versions. For example TLSv1.3 is 0x0304 (772 decimal), and
- TLSv1.2 is 0x0303 (771 decimal). A 0 indicates that there is no defined minimum
- or maximum. A -1 indicates that the group should not be used in that protocol.
- =back
- =head1 EXAMPLES
- This is an example of a simple provider made available as a
- dynamically loadable module.
- It implements the fictitious algorithm C<FOO> for the fictitious
- operation C<BAR>.
- #include <malloc.h>
- #include <openssl/core.h>
- #include <openssl/core_dispatch.h>
- /* Errors used in this provider */
- #define E_MALLOC 1
- static const OSSL_ITEM reasons[] = {
- { E_MALLOC, "memory allocation failure" }.
- { 0, NULL } /* Termination */
- };
- /*
- * To ensure we get the function signature right, forward declare
- * them using function types provided by openssl/core_dispatch.h
- */
- OSSL_FUNC_bar_newctx_fn foo_newctx;
- OSSL_FUNC_bar_freectx_fn foo_freectx;
- OSSL_FUNC_bar_init_fn foo_init;
- OSSL_FUNC_bar_update_fn foo_update;
- OSSL_FUNC_bar_final_fn foo_final;
- OSSL_FUNC_provider_query_operation_fn p_query;
- OSSL_FUNC_provider_get_reason_strings_fn p_reasons;
- OSSL_FUNC_provider_teardown_fn p_teardown;
- OSSL_provider_init_fn OSSL_provider_init;
- OSSL_FUNC_core_put_error *c_put_error = NULL;
- /* Provider context */
- struct prov_ctx_st {
- OSSL_CORE_HANDLE *handle;
- }
- /* operation context for the algorithm FOO */
- struct foo_ctx_st {
- struct prov_ctx_st *provctx;
- int b;
- };
- static void *foo_newctx(void *provctx)
- {
- struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx));
- if (fooctx != NULL)
- fooctx->provctx = provctx;
- else
- c_put_error(provctx->handle, E_MALLOC, __FILE__, __LINE__);
- return fooctx;
- }
- static void foo_freectx(void *fooctx)
- {
- free(fooctx);
- }
- static int foo_init(void *vfooctx)
- {
- struct foo_ctx_st *fooctx = vfooctx;
- fooctx->b = 0x33;
- }
- static int foo_update(void *vfooctx, unsigned char *in, size_t inl)
- {
- struct foo_ctx_st *fooctx = vfooctx;
- /* did you expect something serious? */
- if (inl == 0)
- return 1;
- for (; inl-- > 0; in++)
- *in ^= fooctx->b;
- return 1;
- }
- static int foo_final(void *vfooctx)
- {
- struct foo_ctx_st *fooctx = vfooctx;
- fooctx->b = 0x66;
- }
- static const OSSL_DISPATCH foo_fns[] = {
- { OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx },
- { OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx },
- { OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init },
- { OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update },
- { OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final },
- { 0, NULL }
- };
- static const OSSL_ALGORITHM bars[] = {
- { "FOO", "provider=chumbawamba", foo_fns },
- { NULL, NULL, NULL }
- };
- static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id,
- int *no_store)
- {
- switch (operation_id) {
- case OSSL_OP_BAR:
- return bars;
- }
- return NULL;
- }
- static const OSSL_ITEM *p_reasons(void *provctx)
- {
- return reasons;
- }
- static void p_teardown(void *provctx)
- {
- free(provctx);
- }
- static const OSSL_DISPATCH prov_fns[] = {
- { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown },
- { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query },
- { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons },
- { 0, NULL }
- };
- int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
- const OSSL_DISPATCH *in,
- const OSSL_DISPATCH **out,
- void **provctx)
- {
- struct prov_ctx_st *pctx = NULL;
- for (; in->function_id != 0; in++)
- switch (in->function_id) {
- case OSSL_FUNC_CORE_PUT_ERROR:
- c_put_error = OSSL_FUNC_core_put_error(in);
- break;
- }
- *out = prov_fns;
- if ((pctx = malloc(sizeof(*pctx))) == NULL) {
- /*
- * ALEA IACTA EST, if the core retrieves the reason table
- * regardless, that string will be displayed, otherwise not.
- */
- c_put_error(handle, E_MALLOC, __FILE__, __LINE__);
- return 0;
- }
- pctx->handle = handle;
- return 1;
- }
- This relies on a few things existing in F<openssl/core_dispatch.h>:
- #define OSSL_OP_BAR 4711
- #define OSSL_FUNC_BAR_NEWCTX 1
- typedef void *(OSSL_FUNC_bar_newctx_fn)(void *provctx);
- static ossl_inline OSSL_FUNC_bar_newctx(const OSSL_DISPATCH *opf)
- { return (OSSL_FUNC_bar_newctx_fn *)opf->function; }
- #define OSSL_FUNC_BAR_FREECTX 2
- typedef void (OSSL_FUNC_bar_freectx_fn)(void *ctx);
- static ossl_inline OSSL_FUNC_bar_newctx(const OSSL_DISPATCH *opf)
- { return (OSSL_FUNC_bar_freectx_fn *)opf->function; }
- #define OSSL_FUNC_BAR_INIT 3
- typedef void *(OSSL_FUNC_bar_init_fn)(void *ctx);
- static ossl_inline OSSL_FUNC_bar_init(const OSSL_DISPATCH *opf)
- { return (OSSL_FUNC_bar_init_fn *)opf->function; }
- #define OSSL_FUNC_BAR_UPDATE 4
- typedef void *(OSSL_FUNC_bar_update_fn)(void *ctx,
- unsigned char *in, size_t inl);
- static ossl_inline OSSL_FUNC_bar_update(const OSSL_DISPATCH *opf)
- { return (OSSL_FUNC_bar_update_fn *)opf->function; }
- #define OSSL_FUNC_BAR_FINAL 5
- typedef void *(OSSL_FUNC_bar_final_fn)(void *ctx);
- static ossl_inline OSSL_FUNC_bar_final(const OSSL_DISPATCH *opf)
- { return (OSSL_FUNC_bar_final_fn *)opf->function; }
- =head1 SEE ALSO
- L<provider(7)>
- =head1 HISTORY
- The concept of providers and everything surrounding them was
- introduced in OpenSSL 3.0.
- =head1 COPYRIGHT
- Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
- Licensed under the Apache License 2.0 (the "License"). You may not use
- this file except in compliance with the License. You can obtain a copy
- in the file LICENSE in the source distribution or at
- L<https://www.openssl.org/source/license.html>.
- =cut
|