PROVIDER-CIPHER(7ossl)

๐Ÿ“ฆ
version 15.1 ยท 3 versions
, in freebsd 15.1

๐ŸŒธ PROVIDER-CIPHER ๐ŸŒธ

the provider-cipher page from the OpenSSL manual โ€” PROVIDER-CIPHER(7ossl) ๐ŸŽ€ this is part 1 of 3, bestie, so buckle up ๐Ÿฆ‹


โœจ NAME โœจ

provider-cipher โ€” the cipher library <-> provider functions ๐Ÿ’ซ

okay so real talk: this is the bridge page. it's where the cipher library side and the provider side meet and awkwardly say hi to each other, and this page is literally the guest list of function pointers that make that happen. ๐Ÿซถ


๐Ÿ’… SYNOPSIS ๐Ÿ’…

Grab your snacks, here's the whole cast of characters ๐Ÿ“:

#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[]);

๐Ÿ‘‘ the vibe check on what you just read

#include <openssl/core_dispatch.h> and #include <openssl/core_names.h> โ€” those are the two headers you're pulling in, periodt. โœจ

And then the disclaimer that matters, straight from the source comment, no paraphrasing:

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.

like, they're not callable functions, bestie โ€” they're the shapes of slots you fill in inside an OSSL_DISPATCH array. do not go trying to dlsym them and act surprised ๐Ÿ’€

The groupings, since the original sorts them for us:

  • Context management ๐Ÿงš โ€” OSSL_FUNC_cipher_newctx, OSSL_FUNC_cipher_freectx, OSSL_FUNC_cipher_dupctx
  • Encryption/decryption ๐Ÿ”ฅ โ€” OSSL_FUNC_cipher_encrypt_init, OSSL_FUNC_cipher_decrypt_init, OSSL_FUNC_cipher_encrypt_skey_init (twice, yes, that's how it's printed โ€” no cap, I'm not gaslighting you, don't come for me ๐Ÿ™ˆ), OSSL_FUNC_cipher_update, OSSL_FUNC_cipher_final, OSSL_FUNC_cipher_cipher
  • Encryption/decryption using cipher pipeline ๐ŸŒˆ โ€” OSSL_FUNC_cipher_pipeline_encrypt_init, OSSL_FUNC_cipher_pipeline_decrypt_init, OSSL_FUNC_cipher_pipeline_update, OSSL_FUNC_cipher_pipeline_final
  • Cipher parameter descriptors ๐ŸŽ€ โ€” OSSL_FUNC_cipher_gettable_params
  • Cipher operation parameter descriptors โญ โ€” OSSL_FUNC_cipher_gettable_ctx_params, OSSL_FUNC_cipher_settable_ctx_params
  • Cipher parameters ๐Ÿ’œ โ€” OSSL_FUNC_cipher_get_params
  • Cipher operation parameters ๐Ÿฆ‹ โ€” OSSL_FUNC_cipher_get_ctx_params, OSSL_FUNC_cipher_set_ctx_params

and yes โ€” the pipeline block up there really does have those stray extra )) and those dangling params[])) endings. that's the original text, character for character. copy signatures exactly as written, extra parens and all ๐Ÿ˜ญ don't "fix" them, don't be a hero, i'm just the messenger ๐Ÿซถ

also provctx, cctx, skeydata, key, keylen, iv, ivlen, params, numpipes, out, outl, outsize, in, inl โ€” every one of those is a real argument name, and every const unsigned char * / size_t / OSSL_PARAM type is exactly what it says. slay ๐Ÿ’…


ok and that's it for the synopsis portion โ€” keep reading, there's more of this page coming ๐Ÿ’–โœจ

โœจ DESCRIPTION โœจ

Okay bestie, real talk: this page is primarily aimed at provider authors. Like, the people writing the actual cipher algorithms behind the scenes. If thatโ€™s not you, go peek at provider(7) for the bigger picture. ๐Ÿ’…

The CIPHER operation is how providers implement cipher algorithms and make them available to apps through the API functions EVP_EncryptInit_ex(3), EVP_EncryptUpdate(3), and EVP_EncryptFinal(3) โ€” plus all the decrypt equivalents and other related functions. Slay.

All the โ€œfunctionsโ€ weโ€™re about to talk about are passed as function pointers between libcrypto and the provider in OSSL_DISPATCH(3) arrays via OSSL_ALGORITHM(3) arrays. Those arrays get returned by the providerโ€™s provider_query_operation() function (check โ€œProvider Functionsโ€ in provider-base(7)). Itโ€™s giving very backstage pass energy.

Every single one of these โ€œfunctionsโ€ has a matching function type definition named OSSL_FUNC_{name}_fn, and a helper function to grab the function pointer from an OSSL_DISPATCH(3) element named OSSL_FUNC_{name}. Example time, because why not: 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 provided as macros in openssl-core_dispatch.h(7), like this:

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 doesnโ€™t have to implement all of these. But to be a consistent set of functions, you need at least a complete set of โ€œencryptโ€ functions, or a complete set of โ€œdecryptโ€ functions, or a single โ€œcipherโ€ function. Same energy for pipelines: you can have a complete set of pipeline โ€œencryptโ€ functions, and/or a complete set of pipeline โ€œdecryptโ€ functions. In all cases, OSSL_FUNC_cipher_get_params and both OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx must be present. Everything else is optional. No pressure. (Okay, some pressure.)

๐Ÿงธ 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. That pointer gets passed back in a bunch of the other cipher operation function calls. The provctx parameter is the provider context generated during provider initialisation (see provider(7)). Itโ€™s the main character of context creation.
  • OSSL_FUNC_cipher_freectx() โ€” gets a pointer to the provider-side cipher context in the cctx parameter. This function should free any resources associated with that context. Clean up your room, bestie. ๐Ÿงน
  • OSSL_FUNC_cipher_dupctx() โ€” should duplicate the provider-side cipher context in the cctx parameter and return the duplicate copy. Copy-paste but make it legal.

๐Ÿ” 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(). Key, IV, params โ€” the holy trinity. ๐Ÿ”‘
  • OSSL_FUNC_cipher_decrypt_init() โ€” exactly the same as OSSL_FUNC_cipher_encrypt_init() except it initialises the context for a decryption operation. Decrypt girlies rise.
  • OSSL_FUNC_cipher_encrypt_skey_init() and OSSL_FUNC_cipher_decrypt_skey_init() โ€” 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. Itโ€™s giving โ€œkeys but make them mysteriousโ€.
  • OSSL_FUNC_cipher_update() โ€” 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 goes 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. So donโ€™t worry about buffer overlap unless itโ€™s the same pointer. Periodt. ๐Ÿ’…
  • 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 goes to *outl, which should not exceed outsize bytes. The same expectations apply to outsize as documented for EVP_EncryptFinal(3) and EVP_DecryptFinal(3). Final girl energy, literally. ๐ŸŽ€
  • 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. Raw cipher, no padding, no fuss. ๐Ÿ’€
  • OSSL_FUNC_cipher_pipeline_encrypt_init(), OSSL_FUNC_cipher_pipeline_decrypt_init(), OSSL_FUNC_cipher_pipeline_update(), and OSSL_FUNC_cipher_pipeline_final() โ€” similar to the non-pipeline variants, but 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. Pipeline gang, we love you. ๐Ÿซถ

๐ŸŽ›๏ธ 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. Itโ€™s giving โ€œtell me about yourselfโ€.
  • 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. Additive, not replace-y.
  • 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. Yes, the original says โ€œdetails detailsโ€ โ€” weโ€™re not fixing it, weโ€™re keeping the vibe. ๐Ÿ˜ญ
  • 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. Descriptor arrays โ€” the receipts of whatโ€™s supported. ๐Ÿงพ

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. So donโ€™t assume every cipher knows every param. Read the room. ๐Ÿ’…


๐ŸŒŸ RETURN VALUES ๐ŸŒŸ

  • OSSL_FUNC_cipher_newctx() and OSSL_FUNC_cipher_dupctx() โ€” should return the newly created provider-side cipher context, or NULL on failure. No context, no party. ๐Ÿ™ˆ
  • 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. Binary queen. ๐Ÿ‘‘
  • 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. No array, no problem โ€” well, NULL, but you know. ๐Ÿ’€

๐Ÿ“š 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 โœจ

Okay so storytime, bestie ๐Ÿ“– โ€” the provider CIPHER interface? Literally brand new in OpenSSL 3.0. Like, that's when it was introduced introduced. No cap.

And the glow-up didn't stop there: OSSL_FUNC_cipher_encrypt_skey_init() and OSSL_FUNC_cipher_decrypt_skey_init() are the newer era โ€” they didn't exist until OpenSSL 3.5. So if you're kicking it on an older version and those two don't compile, that's not you being bad at code, that's just the timeline, fr fr ๐Ÿ•ฐ๏ธโœจ


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

Real talk: the whole "you may not use this file except in compliance with the License" thing is not a vibe suggestion ๐Ÿ’… โ€” it's the actual rule. Read the license, bestie, it's giving required reading ๐Ÿ“š

๐ŸŒธ and that's the whole page, you absolute icon โ€” go forth and write your ciphers ๐ŸŒธ

This queen of a manpage is from OpenSSL 3.5.6, dated 2026-04-07, and its name is PROVIDER-CIPHER(7ossl) โ€” say it with the respect it deserves ๐Ÿ‘‘๐Ÿซถ

๐Ÿ“ฆ where this page comes from