provider

title: provider(7ossl)

text:
# provider(7ossl)

## NAME
provider - OpenSSL operation implementation providers

## SYNOPSIS
\#include <openssl/provider.h>

## DESCRIPTION

### General
This page contains information useful to provider authors.

A provider, in OpenSSL terms, is a unit of code that provides one or more implementations for various operations for diverse algorithms that one might want to perform.

An operation is something one wants to do, such as encryption and decryption, key derivation, MAC calculation, signing and verification, etc.

An algorithm is a named method to perform an operation. Very often, the algorithms revolve around cryptographic operations, but may also revolve around other types of operation, such as managing certain types of objects.

See crypto(7) for further details.

### Provider
A provider offers an initialization function, as a set of base functions in the form of an OSSL_DISPATCH(3) array, and by extension, a set of OSSL_ALGORITHM(3)s (see openssl-core.h(7)). It may be a dynamically loadable module, or may be built-in, in OpenSSL libraries or in the application. If it's a dynamically loadable module, the initialization function must be named "OSSL_provider_init" and must be exported. If it's built-in, the initialization function may have any name.

The initialization function must have the following signature:

```
 int NAME(const OSSL_CORE_HANDLE *handle,
          const OSSL_DISPATCH *in, const OSSL_DISPATCH **out,
          void **provctx);
```

handle is the OpenSSL library object for the provider, and works as a handle for everything the OpenSSL libraries need to know about the provider. For the provider itself, it is passed to some of the functions given in the dispatch array in.

in is a dispatch array of base functions offered by the OpenSSL libraries, and the available functions are further described in provider-base(7).

*out must be assigned a dispatch array of base functions that the provider offers to the OpenSSL libraries. The functions that may be offered are further described in provider-base(7), and they are the central means of communication between the OpenSSL libraries and the provider.

*provctx should be assigned a provider specific context to allow the provider multiple simultaneous uses. This pointer will be passed to various operation functions offered by the provider.

Note that the provider will not be made available for applications to use until the initialization function has completed and returned successfully.

One of the functions the provider offers to the OpenSSL libraries is the central mechanism for the OpenSSL libraries to get access to operation implementations for diverse algorithms. Its referred to with the number OSSL_FUNC_PROVIDER_QUERY_OPERATION and has the following signature:

```
 const OSSL_ALGORITHM *provider_query_operation(void *provctx,
                                                int operation_id,
                                                const int *no_store);
```

provctx is the provider specific context that was passed back by the initialization function.

operation_id is an operation identity (see "Operations" below).

no_store is a flag back to the OpenSSL libraries which, when nonzero, signifies that the OpenSSL libraries will not store a reference to the returned data in their internal store of implementations.

The returned OSSL_ALGORITHM(3) is the foundation of any OpenSSL library API that uses providers for their implementation, most commonly in the fetching type of functions (see "ALGORITHM FETCHING" in crypto(7)).

### Operations
Operations are referred to with numbers, via macros with names starting with "OSSL_OP_".

With each operation comes a set of defined function types that a provider may or may not offer, depending on its needs.

Currently available operations are:

Digests

In the OpenSSL libraries, the corresponding method object is EVP_MD. The number for this operation is OSSL_OP_DIGEST. The functions the provider can offer are described in provider-digest(7).

Symmetric ciphers

In the OpenSSL libraries, the corresponding method object is EVP_CIPHER. The number for this operation is OSSL_OP_CIPHER. The functions the provider can offer are described in provider-cipher(7).

Message Authentication Code (MAC)

In the OpenSSL libraries, the corresponding method object is EVP_MAC. The number for this operation is OSSL_OP_MAC. The functions the provider can offer are described in provider-mac(7).

Key Derivation Function (KDF)

In the OpenSSL libraries, the corresponding method object is EVP_KDF. The number for this operation is OSSL_OP_KDF. The functions the provider can offer are described in provider-kdf(7).

Key Exchange

In the OpenSSL libraries, the corresponding method object is EVP_KEYEXCH. The number for this operation is OSSL_OP_KEYEXCH. The functions the provider can offer are described in provider-keyexch(7).

Asymmetric Ciphers

In the OpenSSL libraries, the corresponding method object is EVP_ASYM_CIPHER. The number for this operation is OSSL_OP_ASYM_CIPHER. The functions the provider can offer are described in provider-asym_cipher(7).

Asymmetric Key Encapsulation

In the OpenSSL libraries, the corresponding method object is EVP_KEM. The number for this operation is OSSL_OP_KEM. The functions the provider can offer are described in provider-kem(7).

Encoding

In the OpenSSL libraries, the corresponding method object is OSSL_ENCODER. The number for this operation is OSSL_OP_ENCODER. The functions the provider can offer are described in provider-encoder(7).

Decoding

In the OpenSSL libraries, the corresponding method object is OSSL_DECODER. The number for this operation is OSSL_OP_DECODER. The functions the provider can offer are described in provider-decoder(7).

Random Number Generation

The number for this operation is OSSL_OP_RAND. The functions the provider can offer for random number generation are described in provider-rand(7).

Key Management

The number for this operation is OSSL_OP_KEYMGMT. The functions the provider can offer for key management are described in provider-keymgmt(7).

Signing and Signature Verification

The number for this operation is OSSL_OP_SIGNATURE. The functions the provider can offer for digital signatures are described in provider-signature(7).

Store Management

The number for this operation is OSSL_OP_STORE. The functions the provider can offer for store management are described in provider-storemgmt(7).

Algorithm naming

Algorithm names are case insensitive. Any particular algorithm can have multiple aliases associated with it. The canonical OpenSSL naming scheme follows this format:

ALGNAME[VERSION?][-SUBNAME[VERSION?]?][-SIZE?][-MODE?]

VERSION is only present if there are multiple versions of an algorithm (e.g. MD2, MD4, MD5). It may be omitted if there is only one version.

SUBNAME may be present where multiple algorithms are combined together, e.g. MD5-SHA1.

SIZE is only present if multiple versions of an algorithm exist with different sizes (e.g. AES-128-CBC, AES-256-CBC)

MODE is only present where applicable.

Other aliases may exist for example where standards bodies or common practice use alternative names or names that OpenSSL has used historically.

Provider dependencies

Providers may depend for their proper operation on the availability of (functionality implemented in) other providers. As there is no mechanism to express such dependencies towards the OpenSSL core, provider authors must take care that such dependencies are either completely avoided or made visible to users, e.g., by documentation and/or defensive programming, e.g., outputting error messages if required external dependencies are not available, e.g., when no provider implementing the required functionality has been activated. In particular, provider initialization should not depend on other providers already having been initialized.

Note on naming clashes

It is possible to register the same algorithm name from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation of a particular algorithm will be returned. Such naming clashes may also occur if algorithms only differ in capitalization as "Algorithm naming" is case insensitive.

## OPENSSL PROVIDERS
OpenSSL provides a number of its own providers. These are the default, base, fips, legacy and null providers. See crypto(7) for an overview of these providers.

## SEE ALSO
EVP_DigestInit_ex(3), EVP_EncryptInit_ex(3), OSSL_LIB_CTX(3), EVP_set_default_properties(3), EVP_MD_fetch(3), EVP_CIPHER_fetch(3), EVP_KEYMGMT_fetch(3), openssl-core.h(7), provider-base(7), provider-digest(7), provider-cipher(7), provider-keyexch(7)

## HISTORY
The concept of providers and everything surrounding them was introduced in OpenSSL 3.0.

## COPYRIGHT
Copyright 2019-2022 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 <https://www.openssl.org/source/license.html>.


package: openssl

title: provider-asym_cipher(7ossl)

summary: The asym_cipher library <\-> provider functions

text:
# provider-asym_cipher(7ossl)

## NAME
provider-asym_cipher - The asym_cipher library <-> provider functions

## SYNOPSIS

```
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.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.
  */
 /* Context management */
 void *OSSL_FUNC_asym_cipher_newctx(void *provctx);
 void OSSL_FUNC_asym_cipher_freectx(void *ctx);
 void *OSSL_FUNC_asym_cipher_dupctx(void *ctx);
 /* Encryption */
 int OSSL_FUNC_asym_cipher_encrypt_init(void *ctx, void *provkey,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_asym_cipher_encrypt(void *ctx, unsigned char *out, size_t *outlen,
                                   size_t outsize, const unsigned char *in,
                                   size_t inlen);
 /* Decryption */
 int OSSL_FUNC_asym_cipher_decrypt_init(void *ctx, void *provkey,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_asym_cipher_decrypt(void *ctx, unsigned char *out, size_t *outlen,
                                   size_t outsize, const unsigned char *in,
                                   size_t inlen);
 /* Asymmetric Cipher parameters */
 int OSSL_FUNC_asym_cipher_get_ctx_params(void *ctx, OSSL_PARAM params[]);
 const OSSL_PARAM *OSSL_FUNC_asym_cipher_gettable_ctx_params(void *provctx);
 int OSSL_FUNC_asym_cipher_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
 const OSSL_PARAM *OSSL_FUNC_asym_cipher_settable_ctx_params(void *provctx);
```

## DESCRIPTION
This documentation is primarily aimed at provider authors. See provider(7) for further information.

The asymmetric cipher (OSSL_OP_ASYM_CIPHER) operation enables providers to implement asymmetric cipher algorithms and make them available to applications via the API functions EVP_PKEY_encrypt(3), EVP_PKEY_decrypt(3) and other related functions).

All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays via OSSL_ALGORITHM(3) arrays that are returned by the provider's provider_query_operation() function (see "Provider Functions" in provider-base(7)).

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from an OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. For example, the "function" OSSL_FUNC_asym_cipher_newctx() has these:

```
 typedef void *(OSSL_FUNC_asym_cipher_newctx_fn)(void *provctx);
 static ossl_inline OSSL_FUNC_asym_cipher_newctx_fn
     OSSL_FUNC_asym_cipher_newctx(const OSSL_DISPATCH *opf);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

```
 OSSL_FUNC_asym_cipher_newctx               OSSL_FUNC_ASYM_CIPHER_NEWCTX
 OSSL_FUNC_asym_cipher_freectx              OSSL_FUNC_ASYM_CIPHER_FREECTX
 OSSL_FUNC_asym_cipher_dupctx               OSSL_FUNC_ASYM_CIPHER_DUPCTX
 OSSL_FUNC_asym_cipher_encrypt_init         OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT
 OSSL_FUNC_asym_cipher_encrypt              OSSL_FUNC_ASYM_CIPHER_ENCRYPT
 OSSL_FUNC_asym_cipher_decrypt_init         OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT
 OSSL_FUNC_asym_cipher_decrypt              OSSL_FUNC_ASYM_CIPHER_DECRYPT
 OSSL_FUNC_asym_cipher_get_ctx_params       OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS
 OSSL_FUNC_asym_cipher_gettable_ctx_params  OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS
 OSSL_FUNC_asym_cipher_set_ctx_params       OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS
 OSSL_FUNC_asym_cipher_settable_ctx_params  OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS
```

An asymmetric cipher algorithm implementation may not implement all of these functions. In order to be a consistent set of functions a provider must implement OSSL_FUNC_asym_cipher_newctx and OSSL_FUNC_asym_cipher_freectx. It must also implement both of OSSL_FUNC_asym_cipher_encrypt_init and OSSL_FUNC_asym_cipher_encrypt, or both of OSSL_FUNC_asym_cipher_decrypt_init and OSSL_FUNC_asym_cipher_decrypt. OSSL_FUNC_asym_cipher_get_ctx_params is optional but if it is present then so must OSSL_FUNC_asym_cipher_gettable_ctx_params. Similarly, OSSL_FUNC_asym_cipher_set_ctx_params is optional but if it is present then so must OSSL_FUNC_asym_cipher_settable_ctx_params.

An asymmetric cipher algorithm must also implement some mechanism for generating, loading or importing keys via the key management (OSSL_OP_KEYMGMT) operation. See provider-keymgmt(7) for further details.

### Context Management Functions
OSSL_FUNC_asym_cipher_newctx() should create and return a pointer to a provider side structure for holding context information during an asymmetric cipher operation. A pointer to this context will be passed back in a number of the other asymmetric cipher operation function calls. The parameter provctx is the provider context generated during provider initialisation (see provider(7)).

OSSL_FUNC_asym_cipher_freectx() is passed a pointer to the provider side asymmetric cipher context in the ctx parameter. This function should free any resources associated with that context.

OSSL_FUNC_asym_cipher_dupctx() should duplicate the provider side asymmetric cipher context in the ctx parameter and return the duplicate copy.

### Encryption Functions
OSSL_FUNC_asym_cipher_encrypt_init() initialises a context for an asymmetric encryption given a provider side asymmetric cipher context in the ctx parameter, and a pointer to a provider key object in the provkey parameter. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_asym_cipher_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)). OSSL_FUNC_asym_cipher_encrypt() performs the actual encryption itself. A previously initialised asymmetric cipher context is passed in the ctx parameter. The data to be encrypted is pointed to by the in parameter which is inlen bytes long. Unless out is NULL, the encrypted data should be written to the location pointed to by the out parameter and it should not exceed outsize bytes in length. The length of the encrypted data should be written to *outlen. If out is NULL then the maximum length of the encrypted data should be written to *outlen.

### Decryption Functions
OSSL_FUNC_asym_cipher_decrypt_init() initialises a context for an asymmetric decryption given a provider side asymmetric cipher context in the ctx parameter, and a pointer to a provider key object in the provkey parameter. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_asym_cipher_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)).

OSSL_FUNC_asym_cipher_decrypt() performs the actual decryption itself. A previously initialised asymmetric cipher context is passed in the ctx parameter. The data to be decrypted is pointed to by the in parameter which is inlen bytes long. Unless out is NULL, the decrypted data should be written to the location pointed to by the out parameter and it should not exceed outsize bytes in length. The length of the decrypted data should be written to *outlen. If out is NULL then the maximum length of the decrypted data should be written to *outlen.

### Asymmetric Cipher Parameters
See OSSL_PARAM(3) for further details on the parameters structure used by the OSSL_FUNC_asym_cipher_get_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() functions.

OSSL_FUNC_asym_cipher_get_ctx_params() gets asymmetric cipher parameters associated with the given provider side asymmetric cipher context ctx and stores them in params. Passing NULL for params should return true.

OSSL_FUNC_asym_cipher_set_ctx_params() sets the asymmetric cipher parameters associated with the given provider side asymmetric cipher context ctx to params. Any parameter settings are additional to any that were previously set. Passing NULL for params should return true.

Parameters currently recognised by built-in asymmetric cipher algorithms are as follows. Not all parameters are relevant to, or are understood by all asymmetric cipher algorithms:

"pad-mode" (OSSL_ASYM_CIPHER_PARAM_PAD_MODE) <UTF8 string> OR <integer>

The type of padding to be used. The interpretation of this value will depend on the algorithm in use.

"digest" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST) <UTF8 string>

Gets or sets the name of the OAEP digest algorithm used when OAEP padding is in use.

"digest" (OSSL_ASYM_CIPHER_PARAM_DIGEST) <UTF8 string>

Gets or sets the name of the digest algorithm used by the algorithm (where applicable).

"digest-props" (OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the OAEP digest algorithm.

"digest-props" (OSSL_ASYM_CIPHER_PARAM_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the cipher digest algorithm.

"mgf1-digest" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST) <UTF8 string>

Gets or sets the name of the MGF1 digest algorithm used when OAEP or PSS padding is in use.

"mgf1-digest-props" (OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS) <UTF8 string>

Gets or sets the properties to use when fetching the MGF1 digest algorithm.

"oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string ptr>

Gets the OAEP label used when OAEP padding is in use.

"oaep-label" (OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL) <octet string>

Sets the OAEP label used when OAEP padding is in use.

"tls-client-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer>

The TLS protocol version first requested by the client.

"tls-negotiated-version" (OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION) <unsigned integer>

The negotiated TLS protocol version.

"implicit-rejection" (OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION) <unsigned integer>

Gets or sets the use of the implicit rejection mechanism for RSA PKCS#1 v1.5 decryption. When set (non zero value), the decryption API will return a deterministically random value if the PKCS#1 v1.5 padding check fails. This makes exploitation of the Bleichenbacher significantly harder, even if the code using the RSA decryption API is not implemented in side-channel free manner. Set by default in OpenSSL providers.

The OpenSSL FIPS provider also supports the following parameters:

"fips-indicator" (OSSL_ASYM_CIPHER_PARAM_FIPS_APPROVED_INDICATOR) <integer>

A getter that returns 1 if the operation is FIPS approved, or 0 otherwise. This may be used after calling either OSSL_FUNC_asym_cipher_encrypt() or OSSL_FUNC_asym_cipher_decrypt(). It may return 0 if "key-check" is set to 0.

"key-check" (OSSL_ASYM_CIPHER_PARAM_FIPS_KEY_CHECK) <integer>

If required this parameter should be set using either OSSL_FUNC_asym_cipher_encrypt_init() or OSSL_FUNC_asym_cipher_decrypt_init(). The default value of 1 causes an error during the init if the key is not FIPS approved (e.g. The key has a security strength of less than 112 bits). Setting this to 0 will ignore the error and set the approved "fips-indicator" to 0. This option breaks FIPS compliance if it causes the approved "fips-indicator" to return 0.

OSSL_FUNC_asym_cipher_gettable_ctx_params() and OSSL_FUNC_asym_cipher_settable_ctx_params() get a constant OSSL_PARAM(3) array that describes the gettable and settable parameters, i.e. parameters that can be used with OSSL_FUNC_asym_cipherget_ctx_params() and OSSL_FUNC_asym_cipher_set_ctx_params() respectively.

## RETURN VALUES
OSSL_FUNC_asym_cipher_newctx() and OSSL_FUNC_asym_cipher_dupctx() should return the newly created provider side asymmetric cipher context, or NULL on failure.

All other functions should return 1 for success or 0 on error.

## SEE ALSO
provider(7)

## HISTORY
The provider ASYM_CIPHER interface was introduced in OpenSSL 3.0. The Asymmetric Cipher Parameters "fips-indicator" and "key-check" were added in OpenSSL 3.4.

## COPYRIGHT
Copyright 2019-2025 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 <https://www.openssl.org/source/license.html>.

branch: sisyphus


provider-base

title: provider-base(7ossl)

summary: base

text:
# provider-base(7ossl)

## NAME
provider-base - The basic OpenSSL library <-> provider functions

## 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[]);
 typedef void (*OSSL_thread_stop_handler_fn)(void *arg);
 int core_thread_start(const OSSL_CORE_HANDLE *handle,
                       OSSL_thread_stop_handler_fn handfn,
                       void *arg);
 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);
 int core_obj_add_sigid(const OSSL_CORE_HANDLE *prov, const char  *sign_name,
                        const char *digest_name, const char *pkey_name);
 int core_obj_create(const OSSL_CORE_HANDLE *handle, const char *oid,
                     const char *sn, const char *ln);
 /*
  * 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_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);
 unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen);
 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_up_ref(OSSL_CORE_BIO *bio);
 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 OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, 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);
 size_t get_user_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);
 void cleanup_user_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);
 size_t get_user_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);
 void cleanup_user_nonce(const OSSL_CORE_HANDLE *handle,
                         unsigned char *buf, size_t len);
 /* Functions for querying the providers in the application library context */
 int provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
                     int (*create_cb)(const OSSL_CORE_HANDLE *provider,
                                      void *cbdata),
                     int (*remove_cb)(const OSSL_CORE_HANDLE *provider,
                                      void *cbdata),
                     int (*global_props_cb)(const char *props, void *cbdata),
                     void *cbdata);
 void provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle);
 const char *provider_name(const OSSL_CORE_HANDLE *prov);
 void *provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov);
 const OSSL_DISPATCH *provider_get0_dispatch(const OSSL_CORE_HANDLE *prov);
 int provider_up_ref(const OSSL_CORE_HANDLE *prov, int activate);
 int provider_free(const OSSL_CORE_HANDLE *prov, int deactivate);
 /* 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);
 void provider_unquery_operation(void *provctx, int operation_id,
                                 const OSSL_ALGORITHM *algs);
 const OSSL_ITEM *provider_get_reason_strings(void *provctx);
 int provider_get_capabilities(void *provctx, const char *capability,
                               OSSL_CALLBACK *cb, void *arg);
 int provider_self_test(void *provctx);
```

## DESCRIPTION
All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays, in the call of the provider initialization function. See "Provider" in provider(7) for a description of the initialization function. They are known as "upcalls".

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from a OSSL_DISPATCH(3) element named 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);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

For in (the OSSL_DISPATCH(3) array passed from 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_vset_error                OSSL_FUNC_CORE_VSET_ERROR
 core_set_error_mark            OSSL_FUNC_CORE_SET_ERROR_MARK
 core_clear_last_error_mark     OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK
 core_pop_error_to_mark         OSSL_FUNC_CORE_POP_ERROR_TO_MARK
 core_count_to_mark             OSSL_FUNC_CORE_COUNT_TO_MARK
 core_obj_add_sigid             OSSL_FUNC_CORE_OBJ_ADD_SIGID
 core_obj_create                OSSL_FUNC_CORE_OBJ_CREATE
 CRYPTO_malloc                  OSSL_FUNC_CRYPTO_MALLOC
 CRYPTO_zalloc                  OSSL_FUNC_CRYPTO_ZALLOC
 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_write_ex                   OSSL_FUNC_BIO_WRITE_EX
 BIO_up_ref                     OSSL_FUNC_BIO_UP_REF
 BIO_free                       OSSL_FUNC_BIO_FREE
 BIO_vprintf                    OSSL_FUNC_BIO_VPRINTF
 BIO_vsnprintf                  OSSL_FUNC_BIO_VSNPRINTF
 BIO_puts                       OSSL_FUNC_BIO_PUTS
 BIO_gets                       OSSL_FUNC_BIO_GETS
 BIO_ctrl                       OSSL_FUNC_BIO_CTRL
 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_get_user_entropy     OSSL_FUNC_GET_USER_ENTROPY
 ossl_rand_cleanup_entropy      OSSL_FUNC_CLEANUP_ENTROPY
 ossl_rand_cleanup_user_entropy OSSL_FUNC_CLEANUP_USER_ENTROPY
 ossl_rand_get_nonce            OSSL_FUNC_GET_NONCE
 ossl_rand_get_user_nonce       OSSL_FUNC_GET_USER_NONCE
 ossl_rand_cleanup_nonce        OSSL_FUNC_CLEANUP_NONCE
 ossl_rand_cleanup_user_nonce   OSSL_FUNC_CLEANUP_USER_NONCE
 provider_register_child_cb     OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB
 provider_deregister_child_cb   OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB
 provider_name                  OSSL_FUNC_PROVIDER_NAME
 provider_get0_provider_ctx     OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX
 provider_get0_dispatch         OSSL_FUNC_PROVIDER_GET0_DISPATCH
 provider_up_ref                OSSL_FUNC_PROVIDER_UP_REF
 provider_free                  OSSL_FUNC_PROVIDER_FREE
```

For *out (the OSSL_DISPATCH(3) array passed from the provider to 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_unquery_operation     OSSL_FUNC_PROVIDER_UNQUERY_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
```

### Core functions
core_gettable_params() returns a constant array of descriptor OSSL_PARAM(3), for parameters that core_get_params() can handle.

core_get_params() retrieves parameters from the core for the given handle. See "Core parameters" below for a description of currently known parameters.

The core_thread_start() function informs the core that the provider has stated an interest in the current thread. The core will inform the provider when the thread eventually stops. It must be passed the handle for this provider, as well as a callback handfn which will be called when the thread stops. The callback will subsequently be called, with the supplied argument arg, from the thread that is stopping and gets passed the provider context as an argument. This may be useful to perform thread specific clean up such as freeing thread local variables.

core_get_libctx() retrieves the core context in which the library object for the current provider is stored, accessible through the handle. This function is useful only for built-in providers such as the default provider. Never cast this to OSSL_LIB_CTX in a provider that is not built-in as the OSSL_LIB_CTX of the library loading the provider might be a completely different structure than the OSSL_LIB_CTX of the library the provider is linked to. Use OSSL_LIB_CTX_new_child(3) instead to obtain a proper library context that is linked to the application library context.

core_new_error(), core_set_error_debug() and core_vset_error() are building blocks for reporting an error back to the core, with reference to the handle.

core_new_error()

allocates a new thread specific error record. This corresponds to the OpenSSL function ERR_new(3).

core_set_error_debug()

sets debugging information in the current thread specific error record. The debugging information includes the name of the file file, the line line and the function name func where the error occurred. This corresponds to the OpenSSL function ERR_set_debug(3).

core_vset_error()

sets the reason for the error, along with any addition data. The 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 fmt and a set of arguments args, which are treated in the same manner as with BIO_vsnprintf(). file and line may also be passed to indicate exactly where the error occurred or was reported. This corresponds to the OpenSSL function ERR_vset_error(3).

core_set_error_mark()

sets a mark on the current topmost error record if there is one. This corresponds to the OpenSSL function ERR_set_mark(3).

core_clear_last_error_mark()

removes the last mark added if there is one. This corresponds to the OpenSSL function ERR_clear_last_mark(3).

core_pop_error_to_mark()

pops the top of the error stack until a mark is found. The mark is then removed. If there is no mark, the whole stack is removed. This corresponds to the OpenSSL function ERR_pop_to_mark(3).

core_count_to_mark()

returns the number of entries on the error stack above the most recently marked entry, not including that entry. If there is no mark in the error stack, the number of entries in the error stack is returned. This corresponds to the OpenSSL function ERR_count_to_mark(3).

The core_obj_create() function registers a new OID and associated short name sn and long name ln for the given handle. It is similar to the OpenSSL function OBJ_create(3) except that it returns 1 on success or 0 on failure. It will treat as success the case where the OID already exists (even if the short name sn or long name ln provided as arguments differ from those associated with the existing OID, in which case the new names are not associated).

The core_obj_add_sigid() function registers a new composite signature algorithm (sign_name) consisting of an underlying signature algorithm (pkey_name) and digest algorithm (digest_name) for the given handle. It assumes that the OIDs for the composite signature algorithm as well as for the underlying signature and digest algorithms are either already known to OpenSSL or have been registered via a call to core_obj_create(). It corresponds to the OpenSSL function OBJ_add_sigid(3), except that the objects are identified by name rather than a numeric NID. Any name (OID, short name or long name) can be used to identify the object. It will treat as success the case where the composite signature algorithm already exists (even if registered against a different underlying signature or digest algorithm). For digest_name, NULL or an empty string is permissible for signature algorithms that do not need a digest to operate correctly. The function returns 1 on success or 0 on failure.

CRYPTO_malloc(), CRYPTO_zalloc(), 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_write_ex(), BIO_up_ref(), BIO_free(), BIO_vprintf(), BIO_vsnprintf(), BIO_gets(), BIO_puts(), BIO_ctrl(), OPENSSL_cleanse() and OPENSSL_hexstr2buf() correspond exactly to the public functions with the same name. As a matter of fact, the pointers in the OSSL_DISPATCH(3) array are typically direct pointers to those public functions. Note that the BIO functions take an OSSL_CORE_BIO type rather than the standard 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 entropy bytes of randomness and the output will have at least min_len and at most max_len bytes. The buffer address is stored in *pout and the buffer length is returned to the caller. On error, zero is returned.

get_user_entropy() is the same as get_entropy() except that it will attempt to gather seed material via the seed source specified by a call to RAND_set_seed_source_type(3) or via "Random Configuration" in config(5).

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 buf and its length in len.

cleanup_user_entropy() is used to clean up and free the buffer returned by get_user_entropy(). The entropy pointer returned by get_user_entropy() is passed in buf and its length in len.

get_nonce() retrieves a nonce using the passed salt parameter of length salt_len and operating system specific information. The 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 contains at least min_len and at most max_len bytes. The buffer address is stored in *pout and the buffer length returned to the caller. On error, zero is returned.

get_user_nonce() is the same as get_nonce() except that it will attempt to gather seed material via the seed source specified by a call to RAND_set_seed_source_type(3) or via "Random Configuration" in config(5).

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 buf and its length in len.

cleanup_user_nonce() is used to clean up and free the buffer returned by get_user_nonce(). The nonce pointer returned by get_user_nonce() is passed in buf and its length in len.

provider_register_child_cb() registers callbacks for being informed about the loading and unloading of providers in the application's library context. handle is this provider's handle and cbdata is this provider's data that will be passed back to the callbacks. It returns 1 on success or 0 otherwise. These callbacks may be called while holding locks in libcrypto. In order to avoid deadlocks the callback implementation must not be long running and must not call other OpenSSL API functions or upcalls.

create_cb is a callback that will be called when a new provider is loaded into the application's library context. It is also called for any providers that are already loaded at the point that this callback is registered. The callback is passed the handle being used for the new provider being loadded and this provider's data in cbdata. It should return 1 on success or 0 on failure.

remove_cb is a callback that will be called when a new provider is unloaded from the application's library context. It is passed the handle being used for the provider being unloaded and this provider's data in cbdata. It should return 1 on success or 0 on failure.

global_props_cb is a callback that will be called when the global properties from the parent library context are changed. It should return 1 on success or 0 on failure.

provider_deregister_child_cb() unregisters callbacks previously registered via provider_register_child_cb(). If provider_register_child_cb() has been called then provider_deregister_child_cb() should be called at or before the point that this provider's teardown function is called.

provider_name() returns a string giving the name of the provider identified by handle.

provider_get0_provider_ctx() returns the provider context that is associated with the provider identified by prov.

provider_get0_dispatch() gets the dispatch table registered by the provider identified by prov when it initialised.

provider_up_ref() increments the reference count on the provider prov. If activate is nonzero then the provider is also loaded if it is not already loaded. It returns 1 on success or 0 on failure.

provider_free() decrements the reference count on the provider prov. If deactivate is nonzero then the provider is also unloaded if it is not already loaded. It returns 1 on success or 0 on failure.

### 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 provctx.

provider_gettable_params() should return a constant array of descriptor OSSL_PARAM(3), for parameters that provider_get_params() can handle.

provider_get_params() should process the OSSL_PARAM(3) array params, setting the values of the parameters it understands.

provider_query_operation() should return a constant OSSL_ALGORITHM(3) that corresponds to the given operation_id. It should indicate if the core may store a reference to this array by setting *no_store to 0 (core may store a reference) or 1 (core may not store a reference).

provider_unquery_operation() informs the provider that the result of a provider_query_operation() is no longer directly required and that the function pointers have been copied. The operation_id should match that passed to provider_query_operation() and algs should be its return value.

provider_get_reason_strings() should return a constant OSSL_ITEM(3) 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 cb passing it a set of OSSL_PARAM(3)s and the caller supplied argument arg. The OSSL_PARAM(3)s should provide details about the capability with the name given in the capability argument relevant for the provider context 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 "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().

### Provider parameters
provider_get_params() can return the following provider parameters to the core:

"name" (OSSL_PROV_PARAM_NAME) <UTF8 ptr>

This points to a string that should give a unique name for the provider.

"version" (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.

"buildinfo" (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.

"status" (OSSL_PROV_PARAM_STATUS) <unsigned integer>

This returns 0 if the provider has entered an error state, otherwise it returns 1.

provider_gettable_params() should return the above parameters.

### Core parameters
core_get_params() can retrieve the following core parameters for each provider:

"openssl-version" (OSSL_PROV_PARAM_CORE_VERSION) <UTF8 string ptr>

This points to the OpenSSL libraries' full version string, i.e. the string expanded from the macro OPENSSL_VERSION_STR.

"provider-name" (OSSL_PROV_PARAM_CORE_PROV_NAME) <UTF8 string ptr>

This points to the OpenSSL libraries' idea of what the calling provider is named.

"module-filename" (OSSL_PROV_PARAM_CORE_MODULE_FILENAME) <UTF8 string ptr>

This points to a string containing the full filename of the providers module file.

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:

```
 config_diagnostics = 1
 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:

"activate"

pointing at the string "1"

"data1"

pointing at the string "2"

"data2"

pointing at the string "str"

"more.data3"

pointing at the string "foo,bar"

For more information on handling parameters, see OSSL_PARAM(3) as OSSL_PARAM_int(3).

## CAPABILITIES
Capabilities describe some of the services that a provider can offer. Applications can query the capabilities to discover those services.

"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 key exchange (KEX) or 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 OSSL_CAPABILITY_TLS_GROUP_IS_KEM):

"tls-group-name" (OSSL_CAPABILITY_TLS_GROUP_NAME) <UTF8 string>

The name of the group as given in the IANA TLS Supported Groups registry <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.

"tls-group-name-internal" (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.

"tls-group-id" (OSSL_CAPABILITY_TLS_GROUP_ID) <unsigned integer>

The TLS group id value as given in the IANA TLS Supported Groups registry. It is possible to register the same group id from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation for a particular group id will be used.

"tls-group-alg" (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 key exchange or key encapsulation method (KEM), as implied by the optional OSSL_CAPABILITY_TLS_GROUP_IS_KEM flag. The algorithm must support key and parameter generation as well as the key/parameter generation parameter, OSSL_PKEY_PARAM_GROUP_NAME. The group name given via "tls-group-name-internal" above will be passed via OSSL_PKEY_PARAM_GROUP_NAME when libssl wishes to generate keys/parameters.

"tls-group-sec-bits" (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.

"tls-group-is-kem" (OSSL_CAPABILITY_TLS_GROUP_IS_KEM) <unsigned integer>

Boolean flag to describe if the group should be used in key exchange (KEX) mode (0, default) or in 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 keygen then derive against the peer public key. To operate in KEX mode, the group implementation must support the provider functions as described in provider-keyexch(7).

In KEM mode, the client executes keygen and sends its public key, the server executes encapsulate using the client's public key and sends back the resulting ciphertext, finally the client executes decapsulate to retrieve the same shared secret generated by the server's encapsulate. To operate in KEM mode, the group implementation must support the provider functions as described in provider-kem(7).

Both in KEX and KEM mode, the resulting shared secret is then used according to the protocol specification.

"tls-min-tls" (OSSL_CAPABILITY_TLS_GROUP_MIN_TLS) <integer>

"tls-max-tls" (OSSL_CAPABILITY_TLS_GROUP_MAX_TLS) <integer>

"tls-min-dtls" (OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS) <integer>

"tls-max-dtls" (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.

"TLS-SIGALG" Capability

The "TLS-SIGALG" capability can be queried by libssl to discover the list of TLS signature algorithms that a provider can support. Each signature supported can be used for client- or server-authentication in addition to the built-in signature algorithms. TLS1.3 clients can advertise the list of TLS signature algorithms they support in the signature_algorithms extension, and TLS servers can select an algorithm from the offered list that they also support. In this way a provider can add to the list of signature algorithms that libssl already supports with additional ones.

Each TLS signature algorithm that a provider supports should be described via the callback passed in through the provider_get_capabilities function. Each algorithm can have the following details supplied:

"iana-name" (OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME) <UTF8 string>

The name of the signature algorithm as given in the IANA TLS Signature Scheme registry as "Description": <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme>. This value must be supplied.

"iana-code-point" (OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT) <unsigned integer>

The TLS algorithm ID value as given in the IANA TLS SignatureScheme registry. This value must be supplied. It is possible to register the same code point from within different providers. Users should note that if no property query is specified, or more than one implementation matches the property query then it is unspecified which implementation for a particular code point will be used.

"sigalg-name" (OSSL_CAPABILITY_TLS_SIGALG_NAME) <UTF8 string>

A name for the full (possibly composite hash-and-signature) signature algorithm. The provider may, but is not obligated to, provide a signature implementation with this name; if it doesn't, this is assumed to be a composite of a pure signature algorithm and a hash algorithm, which must be given with the parameters "sig-name" and "hash-name". This value must be supplied.

"sigalg-oid" (OSSL_CAPABILITY_TLS_SIGALG_OID) <UTF8 string>

The OID of the "sigalg-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "sigalg-name" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"sig-name" (OSSL_CAPABILITY_TLS_SIGALG_SIG_NAME) <UTF8 string>

The name of the pure signature algorithm that is part of a composite "sigalg-name". If "sigalg-name" is implemented by the provider, this parameter is redundant and must not be given. This value is optional.

"sig-oid" (OSSL_CAPABILITY_TLS_SIGALG_SIG_OID) <UTF8 string>

The OID of the "sig-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "sig-name" parameter for its (short) name. Otherwise, it is assumed to already exist in the object database. This can be done by the provider using the core_obj_create() upcall. This value is optional.

"hash-name" (OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME) <UTF8 string>

The name of the hash algorithm that is part of a composite "sigalg-name". If "sigalg-name" is implemented by the provider, this parameter is redundant and must not be given. This value is optional.

"hash-oid" (OSSL_CAPABILITY_TLS_SIGALG_HASH_OID) <UTF8 string>

The OID of the "hash-name" algorithm in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "hash-name" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"key-type" (OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE) <UTF8 string>

The key type of the public key of applicable certificates. If this parameter isn't present, it's assumed to be the same as "sig-name" if that's present, otherwise "sigalg-name". This value is optional.

"key-type-oid" (OSSL_CAPABILITY_TLS_SIGALG_KEYTYPE_OID) <UTF8 string>

The OID of the "key-type" in canonical numeric text form. If this parameter is given, OBJ_create() will be used to create an OBJ and a NID for this OID, using the "key-type" parameter for its (short) name. Otherwise, it's assumed to already exist in the object database, possibly done by the provider with the core_obj_create() upcall. This value is optional.

"sec-bits" (OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS) <unsigned integer>

The number of bits of security offered by keys of this algorithm. The number of bits should be comparable with the ones given in table 2 and 3 of the NIST SP800-57 document. This number is used to determine the security strength of the algorithm if no digest algorithm has been registered that otherwise defines the security strength. If the signature algorithm implements its own digest internally, this value needs to be set to properly reflect the overall security strength. This value must be supplied.

"tls-min-tls" (OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS) <integer>

"tls-max-tls" (OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS) <integer>

"tls-min-dtls" (OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS) <integer>

"tls-max-dtls" (OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS) <integer>

These parameters can be used to describe the minimum and maximum TLS and DTLS versions supported by the signature algorithm. 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 in either the min or max field indicates that the signature algorithm should not be used in that protocol. Presently, provider signature algorithms are used only with TLS 1.3, if that's enclosed in the specified range.

## NOTES
The core_obj_create() and core_obj_add_sigid() functions were not thread safe in OpenSSL 3.0.

## EXAMPLES
This is an example of a simple provider made available as a dynamically loadable module. It implements the fictitious algorithm "FOO" for the fictitious operation "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" }.
     OSSL_DISPATCH_END
 };
 /*
  * 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 },
     OSSL_DISPATCH_END
 };
 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 },
     OSSL_DISPATCH_END
 };
 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 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_freectx(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; }
```

## SEE ALSO
provider(7)

## HISTORY
The concept of providers and everything surrounding them was introduced in OpenSSL 3.0.

Definitions for OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS and OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS were added in OpenSSL 3.5.

## COPYRIGHT
Copyright 2019-2025 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 <https://www.openssl.org/source/license.html>.


provider-cipher

title: provider-cipher(7ossl)

summary: The cipher library <\-> provider functions

text:
# provider-cipher(7ossl)

## NAME
provider-cipher - The cipher library <-> provider functions

## SYNOPSIS

```
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.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.
  */
 /* Context management */
 void *OSSL_FUNC_cipher_newctx(void *provctx);
 void OSSL_FUNC_cipher_freectx(void *cctx);
 void *OSSL_FUNC_cipher_dupctx(void *cctx);
 /* Encryption/decryption */
 int OSSL_FUNC_cipher_encrypt_init(void *cctx, const unsigned char *key,
                                   size_t keylen, const unsigned char *iv,
                                   size_t ivlen, const OSSL_PARAM params[]);
 int OSSL_FUNC_cipher_decrypt_init(void *cctx, const unsigned char *key,
                                   size_t keylen, const unsigned char *iv,
                                   size_t ivlen, const OSSL_PARAM params[]);
 int OSSL_FUNC_cipher_encrypt_skey_init(void *cctx, void *skeydata,
                                        const unsigned char *iv, size_t ivlen,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_cipher_encrypt_skey_init(void *cctx, void *skeydata,
                                        const unsigned char *iv, size_t ivlen,
                                        const OSSL_PARAM params[]);
 int OSSL_FUNC_cipher_update(void *cctx, unsigned char *out, size_t *outl,
                             size_t outsize, const unsigned char *in, size_t inl);
 int OSSL_FUNC_cipher_final(void *cctx, unsigned char *out, size_t *outl,
                            size_t outsize);
 int OSSL_FUNC_cipher_cipher(void *cctx, unsigned char *out, size_t *outl,
                             size_t outsize, const unsigned char *in, size_t inl);
 /* Encryption/decryption using cipher pipeline */
 int OSSL_FUNC_cipher_pipeline_encrypt_init(void *cctx, const unsigned char *key,
                                            size_t keylen, size_t numpipes,
                                            const unsigned char **iv, size_t ivlen,
                                            const OSSL_PARAM params[]))
 int OSSL_FUNC_cipher_pipeline_decrypt_init(void *cctx, const unsigned char *key,
                                            size_t keylen, size_t numpipes,
                                            const unsigned char **iv, size_t ivlen,
                                            const OSSL_PARAM params[]))
 int OSSL_FUNC_cipher_pipeline_update(void *cctx, size_t numpipes,
                                      unsigned char **out, size_t *outl,
                                      const size_t *outsize,
                                      const unsigned char **in, const size_t *inl))
 int OSSL_FUNC_cipher_pipeline_final(void *cctx, size_t numpipes,
                                     unsigned char **out, size_t *outl,
                                     const size_t *outsize))
 /* Cipher parameter descriptors */
 const OSSL_PARAM *OSSL_FUNC_cipher_gettable_params(void *provctx);
 /* Cipher operation parameter descriptors */
 const OSSL_PARAM *OSSL_FUNC_cipher_gettable_ctx_params(void *cctx,
                                                        void *provctx);
 const OSSL_PARAM *OSSL_FUNC_cipher_settable_ctx_params(void *cctx,
                                                        void *provctx);
 /* Cipher parameters */
 int OSSL_FUNC_cipher_get_params(OSSL_PARAM params[]);
 /* Cipher operation parameters */
 int OSSL_FUNC_cipher_get_ctx_params(void *cctx, OSSL_PARAM params[]);
 int OSSL_FUNC_cipher_set_ctx_params(void *cctx, const OSSL_PARAM params[]);
```

## DESCRIPTION
This documentation is primarily aimed at provider authors. See provider(7) for further information.

The CIPHER operation enables providers to implement cipher algorithms and make them available to applications via the API functions EVP_EncryptInit_ex(3), EVP_EncryptUpdate(3) and EVP_EncryptFinal(3) (as well as the decrypt equivalents and other related functions).

All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays via OSSL_ALGORITHM(3) arrays that are returned by the provider's provider_query_operation() function (see "Provider Functions" in provider-base(7)).

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from an OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. For example, the "function" OSSL_FUNC_cipher_newctx() has these:

```
 typedef void *(OSSL_FUNC_cipher_newctx_fn)(void *provctx);
 static ossl_inline OSSL_FUNC_cipher_newctx_fn
     OSSL_FUNC_cipher_newctx(const OSSL_DISPATCH *opf);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

```
 OSSL_FUNC_cipher_newctx                    OSSL_FUNC_CIPHER_NEWCTX
 OSSL_FUNC_cipher_freectx                   OSSL_FUNC_CIPHER_FREECTX
 OSSL_FUNC_cipher_dupctx                    OSSL_FUNC_CIPHER_DUPCTX
 OSSL_FUNC_cipher_encrypt_init              OSSL_FUNC_CIPHER_ENCRYPT_INIT
 OSSL_FUNC_cipher_decrypt_init              OSSL_FUNC_CIPHER_DECRYPT_INIT
 OSSL_FUNC_cipher_encrypt_skey_init         OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT
 OSSL_FUNC_cipher_decrypt_skey_init         OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT
 OSSL_FUNC_cipher_update                    OSSL_FUNC_CIPHER_UPDATE
 OSSL_FUNC_cipher_final                     OSSL_FUNC_CIPHER_FINAL
 OSSL_FUNC_cipher_cipher                    OSSL_FUNC_CIPHER_CIPHER
 OSSL_FUNC_cipher_pipeline_encrypt_init     OSSL_FUNC_CIPHER_PIPELINE_ENCRYPT_INIT
 OSSL_FUNC_cipher_pipeline_decrypt_init     OSSL_FUNC_CIPHER_PIPELINE_DECRYPT_INIT
 OSSL_FUNC_cipher_pipeline_update           OSSL_FUNC_CIPHER_PIPELINE_UPDATE
 OSSL_FUNC_cipher_pipeline_final            OSSL_FUNC_CIPHER_PIPELINE_FINAL
 OSSL_FUNC_cipher_get_params                OSSL_FUNC_CIPHER_GET_PARAMS
 OSSL_FUNC_cipher_get_ctx_params            OSSL_FUNC_CIPHER_GET_CTX_PARAMS
 OSSL_FUNC_cipher_set_ctx_params            OSSL_FUNC_CIPHER_SET_CTX_PARAMS
 OSSL_FUNC_cipher_gettable_params           OSSL_FUNC_CIPHER_GETTABLE_PARAMS
 OSSL_FUNC_cipher_gettable_ctx_params       OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS
 OSSL_FUNC_cipher_settable_ctx_params       OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS
```

A cipher algorithm implementation may not implement all of these functions. In order to be a consistent set of functions there must at least be a complete set of "encrypt" functions, or a complete set of "decrypt" functions, or a single "cipher" function. Similarly, there can be a complete set of pipeline "encrypt" functions, and/or a complete set of pipeline "decrypt" functions. In all cases the OSSL_FUNC_cipher_get_params and both OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx functions must be present. All other functions are optional.

### Context Management Functions
OSSL_FUNC_cipher_newctx() should create and return a pointer to a provider side structure for holding context information during a cipher operation. A pointer to this context will be passed back in a number of the other cipher operation function calls. The parameter provctx is the provider context generated during provider initialisation (see provider(7)).

OSSL_FUNC_cipher_freectx() is passed a pointer to the provider side cipher context in the cctx parameter. This function should free any resources associated with that context.

OSSL_FUNC_cipher_dupctx() should duplicate the provider side cipher context in the cctx parameter and return the duplicate copy.

### Encryption/Decryption Functions
OSSL_FUNC_cipher_encrypt_init() initialises a cipher operation for encryption given a newly created provider side cipher context in the cctx parameter. The key to be used is given in key which is keylen bytes long. The IV to be used is given in iv which is ivlen bytes long. The params, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_cipher_set_ctx_params().

OSSL_FUNC_cipher_decrypt_init() is the same as OSSL_FUNC_cipher_encrypt_init() except that it initialises the context for a decryption operation.

OSSL_FUNC_cipher_encrypt_skey_init() and OSSL_FUNC_cipher_decrypt_skey_init() are variants of OSSL_FUNC_cipher_encrypt_init() and OSSL_FUNC_cipher_decrypt_init() for working with opaque objects containing provider-specific key handles instead of raw bytes.

OSSL_FUNC_cipher_update() is called to supply data to be encrypted/decrypted as part of a previously initialised cipher operation. The cctx parameter contains a pointer to a previously initialised provider side context. OSSL_FUNC_cipher_update() should encrypt/decrypt inl bytes of data at the location pointed to by in. The encrypted data should be stored in out and the amount of data written to *outl which should not exceed outsize bytes. OSSL_FUNC_cipher_update() may be called multiple times for a single cipher operation. It is the responsibility of the cipher implementation to handle input lengths that are not multiples of the block length. In such cases a cipher implementation will typically cache partial blocks of input data until a complete block is obtained. The pointers out and in may point to the same location, in which case the encryption must be done in-place. If out and in point to different locations, the requirements of EVP_EncryptUpdate(3) and EVP_DecryptUpdate(3) guarantee that the two buffers are disjoint. Similarly, the requirements of EVP_EncryptUpdate(3) and EVP_DecryptUpdate(3) ensure that the buffer pointed to by out contains sufficient room for the operation being performed.

OSSL_FUNC_cipher_final() completes an encryption or decryption started through previous OSSL_FUNC_cipher_encrypt_init() or OSSL_FUNC_cipher_decrypt_init(), and OSSL_FUNC_cipher_update() calls. The cctx parameter contains a pointer to the provider side context. Any final encryption/decryption output should be written to out and the amount of data written to *outl which should not exceed outsize bytes. The same expectations apply to outsize as documented for EVP_EncryptFinal(3) and EVP_DecryptFinal(3).

OSSL_FUNC_cipher_cipher() performs encryption/decryption using the provider side cipher context in the cctx parameter that should have been previously initialised via a call to OSSL_FUNC_cipher_encrypt_init() or OSSL_FUNC_cipher_decrypt_init(). This should call the raw underlying cipher function without any padding. This will be invoked in the provider as a result of the application calling EVP_Cipher(3). The application is responsible for ensuring that the input is a multiple of the block length. The data to be encrypted/decrypted will be in in, and it will be inl bytes in length. The output from the encryption/decryption should be stored in out and the amount of data stored should be put in *outl which should be no more than outsize bytes.

OSSL_FUNC_cipher_pipeline_encrypt_init(), OSSL_FUNC_cipher_pipeline_decrypt_init() OSSL_FUNC_cipher_pipeline_update(), and OSSL_FUNC_cipher_pipeline_final() are similar to the non-pipeline variants, but are used when the application is using cipher pipelining. The numpipes parameter is the number of pipes in the pipeline. The iv parameter is an array of buffers with IVs, each ivlen bytes long. The in and out are arrays of buffer pointers. The inl and outl, outsize are arrays of size_t representing corresponding buffer length as similar to the non-pipeline variants. All arrays are of length numpipes. See EVP_CipherPipelineEncryptInit(3) for more information.

### Cipher Parameters
See OSSL_PARAM(3) for further details on the parameters structure used by these functions.

OSSL_FUNC_cipher_get_params() gets details of the algorithm implementation and stores them in params.

OSSL_FUNC_cipher_set_ctx_params() sets cipher operation parameters for the provider side cipher context cctx to params. Any parameter settings are additional to any that were previously set. Passing NULL for params should return true.

OSSL_FUNC_cipher_get_ctx_params() gets cipher operation details details from the given provider side cipher context cctx and stores them in params. Passing NULL for params should return true.

OSSL_FUNC_cipher_gettable_params(), OSSL_FUNC_cipher_gettable_ctx_params(), and OSSL_FUNC_cipher_settable_ctx_params() all return constant OSSL_PARAM(3) arrays as descriptors of the parameters that OSSL_FUNC_cipher_get_params(), OSSL_FUNC_cipher_get_ctx_params(), and OSSL_FUNC_cipher_set_ctx_params() can handle, respectively. OSSL_FUNC_cipher_gettable_ctx_params() and OSSL_FUNC_cipher_settable_ctx_params() will return the parameters associated with the provider side context cctx in its current state if it is not NULL. Otherwise, they return the parameters associated with the provider side algorithm provctx.

Parameters currently recognised by built-in ciphers are listed in "PARAMETERS" in EVP_EncryptInit(3). Not all parameters are relevant to, or are understood by all ciphers.

## RETURN VALUES
OSSL_FUNC_cipher_newctx() and OSSL_FUNC_cipher_dupctx() should return the newly created provider side cipher context, or NULL on failure.

OSSL_FUNC_cipher_encrypt_init(), OSSL_FUNC_cipher_decrypt_init(), OSSL_FUNC_cipher_update(), OSSL_FUNC_cipher_final(), OSSL_FUNC_cipher_cipher(), OSSL_FUNC_cipher_encrypt_skey_init(), OSSL_FUNC_cipher_decrypt_skey_init(), OSSL_FUNC_cipher_pipeline_encrypt_init(), OSSL_FUNC_cipher_pipeline_decrypt_init(), OSSL_FUNC_cipher_pipeline_update(), OSSL_FUNC_cipher_pipeline_final(), OSSL_FUNC_cipher_get_params(), OSSL_FUNC_cipher_get_ctx_params() and OSSL_FUNC_cipher_set_ctx_params() should return 1 for success or 0 on error.

OSSL_FUNC_cipher_gettable_params(), OSSL_FUNC_cipher_gettable_ctx_params() and OSSL_FUNC_cipher_settable_ctx_params() should return a constant OSSL_PARAM(3) array, or NULL if none is offered.

## SEE ALSO
provider(7), OSSL_PROVIDER-FIPS(7), OSSL_PROVIDER-default(7), OSSL_PROVIDER-legacy(7), EVP_CIPHER-AES(7), EVP_CIPHER-ARIA(7), EVP_CIPHER-BLOWFISH(7), EVP_CIPHER-CAMELLIA(7), EVP_CIPHER-CAST(7), EVP_CIPHER-CHACHA(7), EVP_CIPHER-DES(7), EVP_CIPHER-IDEA(7), EVP_CIPHER-RC2(7), EVP_CIPHER-RC4(7), EVP_CIPHER-RC5(7), EVP_CIPHER-SEED(7), EVP_CIPHER-SM4(7), EVP_CIPHER-NULL(7), life_cycle-cipher(7), EVP_EncryptInit(3)

## HISTORY
The provider CIPHER interface was introduced in OpenSSL 3.0.

The OSSL_FUNC_cipher_encrypt_skey_init() and OSSL_FUNC_cipher_decrypt_skey_init() were introduced in OpenSSL 3.5.

## COPYRIGHT
Copyright 2019-2025 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 <https://www.openssl.org/source/license.html>.


provider-decoder

title: provider-decoder(7ossl)

summary: The OSSL_DECODER library <\-> provider functions

text:
# provider-decoder(7ossl)

## NAME
provider-decoder - The OSSL_DECODER library <-> provider functions

## 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.
  */
 /* Decoder parameter accessor and descriptor */
 const OSSL_PARAM *OSSL_FUNC_decoder_gettable_params(void *provctx);
 int OSSL_FUNC_decoder_get_params(OSSL_PARAM params[]);
 /* Functions to construct / destruct / manipulate the decoder context */
 void *OSSL_FUNC_decoder_newctx(void *provctx);
 void OSSL_FUNC_decoder_freectx(void *ctx);
 const OSSL_PARAM *OSSL_FUNC_decoder_settable_ctx_params(void *provctx);
 int OSSL_FUNC_decoder_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
 /* Functions to check selection support */
 int OSSL_FUNC_decoder_does_selection(void *provctx, int selection);
 /* Functions to decode object data */
 int OSSL_FUNC_decoder_decode(void *ctx, OSSL_CORE_BIO *in,
                              int selection,
                              OSSL_CALLBACK *data_cb, void *data_cbarg,
                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg);
 /* Functions to export a decoded object */
 int OSSL_FUNC_decoder_export_object(void *ctx,
                                       const void *objref, size_t objref_sz,
                                       OSSL_CALLBACK *export_cb,
                                       void *export_cbarg);
```

## DESCRIPTION
The term "decode" is used throughout this manual. This includes but is not limited to deserialization as individual decoders can also do decoding into intermediate data formats.

The DECODER operation is a generic method to create a provider-native object reference or intermediate decoded data from an encoded form read from the given OSSL_CORE_BIO. If the caller wants to decode data from memory, it should provide a BIO_s_mem(3) BIO. The decoded data or object reference is passed along with eventual metadata to the metadata_cb as OSSL_PARAM(3) parameters.

The decoder doesn't need to know more about the OSSL_CORE_BIO pointer than being able to pass it to the appropriate BIO upcalls (see "Core functions" in provider-base(7)).

The DECODER implementation may be part of a chain, where data is passed from one to the next. For example, there may be an implementation to decode an object from PEM to DER, and another one that decodes DER to a provider-native object.

The last decoding step in the decoding chain is usually supposed to create a provider-native object referenced by an object reference. To import that object into a different provider the OSSL_FUNC_decoder_export_object() can be called as the final step of the decoding process.

All "functions" mentioned here are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays via OSSL_ALGORITHM(3) arrays that are returned by the provider's provider_query_operation() function (see "Provider Functions" in provider-base(7)).

All these "functions" have a corresponding function type definition named OSSL_FUNC_{name}_fn, and a helper function to retrieve the function pointer from an OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. For example, the "function" OSSL_FUNC_decoder_decode() has these:

```
 typedef int
     (OSSL_FUNC_decoder_decode_fn)(void *ctx, OSSL_CORE_BIO *in,
                                   int selection,
                                   OSSL_CALLBACK *data_cb, void *data_cbarg,
                                   OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg);
 static ossl_inline OSSL_FUNC_decoder_decode_fn*
     OSSL_FUNC_decoder_decode(const OSSL_DISPATCH *opf);
```

OSSL_DISPATCH(3) arrays are indexed by numbers that are provided as macros in openssl-core_dispatch.h(7), as follows:

```
 OSSL_FUNC_decoder_get_params          OSSL_FUNC_DECODER_GET_PARAMS
 OSSL_FUNC_decoder_gettable_params     OSSL_FUNC_DECODER_GETTABLE_PARAMS
 OSSL_FUNC_decoder_newctx              OSSL_FUNC_DECODER_NEWCTX
 OSSL_FUNC_decoder_freectx             OSSL_FUNC_DECODER_FREECTX
 OSSL_FUNC_decoder_set_ctx_params      OSSL_FUNC_DECODER_SET_CTX_PARAMS
 OSSL_FUNC_decoder_settable_ctx_params OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS
 OSSL_FUNC_decoder_does_selection      OSSL_FUNC_DECODER_DOES_SELECTION
 OSSL_FUNC_decoder_decode              OSSL_FUNC_DECODER_DECODE
 OSSL_FUNC_decoder_export_object       OSSL_FUNC_DECODER_EXPORT_OBJECT
```

### Names and properties
The name of an implementation should match the target type of object it decodes. For example, an implementation that decodes an RSA key should be named "RSA". Likewise, an implementation that decodes DER data from PEM input should be named "DER".

Properties, as defined in the OSSL_ALGORITHM(3) array element of each decoder implementation, can be used to further specify details about an implementation:

input

This property is used to specify what format of input the implementation can decode. This property is mandatory.

OpenSSL providers recognize the following input types:

pem

An implementation with that input type decodes PEM formatted data.

der

An implementation with that input type decodes DER formatted data.

msblob

An implementation with that input type decodes MSBLOB formatted data.

pvk

An implementation with that input type decodes PVK formatted data.

structure

This property is used to specify the structure that the decoded data is expected to have. This property is optional.

Structures currently recognised by built-in decoders:

"type-specific"

Type specific structure.

"pkcs8"

Structure according to the PKCS#8 specification.

"SubjectPublicKeyInfo"

Encoding of public keys according to the Subject Public Key Info of RFC 5280.

The possible values of both these properties is open ended. A provider may very well specify input types and structures that libcrypto doesn't know anything about.

### Subset selections
Sometimes, an object has more than one subset of data that is interesting to treat separately or together. It's possible to specify what subsets are to be decoded, with a set of bits selection that are passed in an int.

This set of bits depend entirely on what kind of provider-side object is to be decoded. For example, those bits are assumed to be the same as those used with provider-keymgmt(7) (see "Key Objects" in provider-keymgmt(7)) when the object is an asymmetric keypair - e.g., OSSL_KEYMGMT_SELECT_PRIVATE_KEY if the object to be decoded is supposed to contain private key components.

OSSL_FUNC_decoder_does_selection() should tell if a particular implementation supports any of the combinations given by selection.

### Context functions
OSSL_FUNC_decoder_newctx() returns a context to be used with the rest of the functions.

OSSL_FUNC_decoder_freectx() frees the given ctx as created by OSSL_FUNC_decoder_newctx().

OSSL_FUNC_decoder_set_ctx_params() sets context data according to parameters from params that it recognises. Unrecognised parameters should be ignored. Passing NULL for params should return true.

OSSL_FUNC_decoder_settable_ctx_params() returns a constant OSSL_PARAM(3) array describing the parameters that OSSL_FUNC_decoder_set_ctx_params() can handle.

See OSSL_PARAM(3) for further details on the parameters structure used by OSSL_FUNC_decoder_set_ctx_params() and OSSL_FUNC_decoder_settable_ctx_params().

### Export function
When a provider-native object is created by a decoder it would be unsuitable for direct use with a foreign provider. The export function allows for exporting the object into that foreign provider if the foreign provider supports the type of the object and provides an import function.

OSSL_FUNC_decoder_export_object() should export the object of size objref_sz referenced by objref as an OSSL_PARAM(3) array and pass that into the export_cb as well as the given export_cbarg.

### Decoding functions
OSSL_FUNC_decoder_decode() should decode the data as read from the OSSL_CORE_BIO in to produce decoded data or an object to be passed as reference in an OSSL_PARAM(3) array along with possible other metadata that was decoded from the input. This OSSL_PARAM(3) array is then passed to the data_cb callback. The selection bits, if relevant, should determine what the input data should contain. The decoding functions also take an OSSL_PASSPHRASE_CALLBACK(3) function pointer along with a pointer to application data cbarg, which should be used when a pass phrase prompt is needed.

It's important to understand that the return value from this function is interpreted as follows:

True (1)

This means "carry on the decoding process", and is meaningful even though this function couldn't decode the input into anything, because there may be another decoder implementation that can decode it into something. The data_cb callback should never be called when this function can't decode the input into anything.

False (0)

This means "stop the decoding process", and is meaningful when the input could be decoded into some sort of object that this function understands, but further treatment of that object results into errors that won't be possible for some other decoder implementation to get a different result.

The conditions to stop the decoding process are at the discretion of the implementation.

### Decoder operation parameters
There are currently no operation parameters currently recognised by the built-in decoders.

Parameters currently recognised by the built-in pass phrase callback:

"info" (OSSL_PASSPHRASE_PARAM_INFO) <UTF8 string>

A string of information that will become part of the pass phrase prompt. This could be used to give the user information on what kind of object it's being prompted for.

## RETURN VALUES
OSSL_FUNC_decoder_newctx() returns a pointer to a context, or NULL on failure.

OSSL_FUNC_decoder_set_ctx_params() returns 1, unless a recognised parameter was invalid or caused an error, for which 0 is returned.

OSSL_FUNC_decoder_settable_ctx_params() returns a pointer to an array of constant OSSL_PARAM(3) elements.

OSSL_FUNC_decoder_does_selection() returns 1 if the decoder implementation supports any of the selection bits, otherwise 0.

OSSL_FUNC_decoder_decode() returns 1 to signal that the decoding process should continue, or 0 to signal that it should stop.

## SEE ALSO
provider(7)

## HISTORY
The DECODER interface was introduced in OpenSSL 3.0.

## COPYRIGHT
Copyright 2019-2025 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 <https://www.openssl.org/source/license.html>.