PROVIDER-CIPHER(7ossl)
๐ธ 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. Theprovctxparameter is the provider context generated during provider initialisation (seeprovider(7)). Itโs the main character of context creation.OSSL_FUNC_cipher_freectx()โ gets a pointer to the provider-side cipher context in thecctxparameter. 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 thecctxparameter 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 thecctxparameter. The key to be used is given inkey, which iskeylenbytes long. The IV to be used is given iniv, which isivlenbytes long. Theparams, if notNULL, should be set on the context in a manner similar to usingOSSL_FUNC_cipher_set_ctx_params(). Key, IV, params โ the holy trinity. ๐OSSL_FUNC_cipher_decrypt_init()โ exactly the same asOSSL_FUNC_cipher_encrypt_init()except it initialises the context for a decryption operation. Decrypt girlies rise.OSSL_FUNC_cipher_encrypt_skey_init()andOSSL_FUNC_cipher_decrypt_skey_init()โ variants ofOSSL_FUNC_cipher_encrypt_init()andOSSL_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. Thecctxparameter contains a pointer to a previously initialised provider-side context.OSSL_FUNC_cipher_update()should encrypt/decryptinlbytes of data at the location pointed to byin. The encrypted data should be stored inout, and the amount of data written goes to*outl, which should not exceedoutsizebytes.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 pointersoutandinmay point to the same location, in which case the encryption must be done in-place. Ifoutandinpoint to different locations, the requirements ofEVP_EncryptUpdate(3)andEVP_DecryptUpdate(3)guarantee that the two buffers are disjoint. Similarly, the requirements ofEVP_EncryptUpdate(3)andEVP_DecryptUpdate(3)ensure that the buffer pointed to byoutcontains 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 previousOSSL_FUNC_cipher_encrypt_init()orOSSL_FUNC_cipher_decrypt_init(), andOSSL_FUNC_cipher_update()calls. Thecctxparameter contains a pointer to the provider-side context. Any final encryption/decryption output should be written toout, and the amount of data written goes to*outl, which should not exceedoutsizebytes. The same expectations apply tooutsizeas documented forEVP_EncryptFinal(3)andEVP_DecryptFinal(3). Final girl energy, literally. ๐OSSL_FUNC_cipher_cipher()โ performs encryption/decryption using the provider-side cipher context in thecctxparameter that should have been previously initialised via a call toOSSL_FUNC_cipher_encrypt_init()orOSSL_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 callingEVP_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 inin, and it will beinlbytes in length. The output from the encryption/decryption should be stored inout, and the amount of data stored should be put in*outl, which should be no more thanoutsizebytes. Raw cipher, no padding, no fuss. ๐OSSL_FUNC_cipher_pipeline_encrypt_init(),OSSL_FUNC_cipher_pipeline_decrypt_init(),OSSL_FUNC_cipher_pipeline_update(), andOSSL_FUNC_cipher_pipeline_final()โ similar to the non-pipeline variants, but used when the application is using cipher pipelining. Thenumpipesparameter is the number of pipes in the pipeline. Theivparameter is an array of buffers with IVs, eachivlenbytes long. Theinandoutare arrays of buffer pointers. Theinlandoutl,outsizeare arrays ofsize_trepresenting corresponding buffer length as similar to the non-pipeline variants. All arrays are of lengthnumpipes. SeeEVP_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 inparams. Itโs giving โtell me about yourselfโ.OSSL_FUNC_cipher_set_ctx_params()โ sets cipher operation parameters for the provider-side cipher contextcctxtoparams. Any parameter settings are additional to any that were previously set. PassingNULLforparamsshould return true. Additive, not replace-y.OSSL_FUNC_cipher_get_ctx_params()โ gets cipher operation details details from the given provider-side cipher contextcctxand stores them inparams. PassingNULLforparamsshould 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(), andOSSL_FUNC_cipher_settable_ctx_params()โ all return constantOSSL_PARAM(3)arrays as descriptors of the parameters thatOSSL_FUNC_cipher_get_params(),OSSL_FUNC_cipher_get_ctx_params(), andOSSL_FUNC_cipher_set_ctx_params()can handle, respectively.OSSL_FUNC_cipher_gettable_ctx_params()andOSSL_FUNC_cipher_settable_ctx_params()will return the parameters associated with the provider-side contextcctxin its current state if it is notNULL. Otherwise, they return the parameters associated with the provider-side algorithmprovctx. 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()andOSSL_FUNC_cipher_dupctx()โ should return the newly created provider-side cipher context, orNULLon 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()andOSSL_FUNC_cipher_set_ctx_params()โ should return1for success or0on error. Binary queen. ๐OSSL_FUNC_cipher_gettable_params(),OSSL_FUNC_cipher_gettable_ctx_params()andOSSL_FUNC_cipher_settable_ctx_params()โ should return a constantOSSL_PARAM(3)array, orNULLif 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 ๐
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
- freebsd 15.1: base 15.1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms