PROVIDER-DIGEST(7SSL)
πΈ provider-digest(7SSL) πΈ
okay bestie sit DOWN because we're reading provider-digest(7SSL), and it's genuinely one of the most important pages in the whole OpenSSL provider saga π
this is the page that explains how a digest β you know, your SHA-2s, your SHAKEs, your "turn a big thing into a small fixed thing" girlies β gets plugged into the provider system. specifically, it's about the holy handshake between the digest library and a provider. the library side says "hey, give me a digest", and the provider side goes "say less, here's my function table" β¨
think of it like this: the provider doesn't hand you an object, it hands you a dispatch table full of function pointers, and every one of those pointers has a name that starts with OSSL_FUNC_digest_. this page is the guest list for that party. no cap. π
π NAME π
provider-digest β the digest library <-> provider functions π¦
like, literally the bridge between those two things. that's the whole vibe. the library wants a digest, the provider has a digest, and this page is the contract they both signed. π
β¨ SYNOPSIS β¨
bestie this is not a real header file you compile against as-is. these are function signatures that show up inOSSL_DISPATCHarrays. the page is very explicit about that and so am I. do not β try to#includeyour way into calling these directly, that's not the move π
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
/*
* Digests support the following function signatures in OSSL_DISPATCH arrays.
* (The function signatures are not actual functions).
*/
/* Context management */
void *OSSL_FUNC_digest_newctx(void *provctx);
void OSSL_FUNC_digest_freectx(void *dctx);
void *OSSL_FUNC_digest_dupctx(void *dctx);
void OSSL_FUNC_digest_copyctx(void *voutctx, void *vinctx);
/* Digest generation */
int OSSL_FUNC_digest_init(void *dctx, const OSSL_PARAM params[]);
int OSSL_FUNC_digest_update(void *dctx, const unsigned char *in, size_t inl);
int OSSL_FUNC_digest_final(void *dctx, unsigned char *out, size_t *outl,
size_t outsz);
int OSSL_FUNC_digest_digest(void *provctx, const unsigned char *in, size_t inl,
unsigned char *out, size_t *outl, size_t outsz);
/* Digest state serialization */
int OSSL_FUNC_digest_serialize(void *dctx, unsigned char *out, size_t *outl);
int OSSL_FUNC_digest_deserialize(void *dctx, const unsigned char *in, size_t inl);
/* Digest parameter descriptors */
const OSSL_PARAM *OSSL_FUNC_digest_gettable_params(void *provctx);
/* Digest operation parameter descriptors */
const OSSL_PARAM *OSSL_FUNC_digest_gettable_ctx_params(void *dctx,
void *provctx);
const OSSL_PARAM *OSSL_FUNC_digest_settable_ctx_params(void *dctx,
void *provctx);
/* Digest parameters */
int OSSL_FUNC_digest_get_params(OSSL_PARAM params[]);
/* Digest operation parameters */
int OSSL_FUNC_digest_set_ctx_params(void *dctx, const OSSL_PARAM params[]);
int OSSL_FUNC_digest_get_ctx_params(void *dctx, OSSL_PARAM params[]);
quick vibe check on what you're looking at up there: six little cliques of functions, all living under the digest umbrella π«Ά
- Context management β
newctx,freectx,dupctx,copyctx. the "make me a lil guy / yeet the lil guy / clone the lil guy" crew π - Digest generation β
init,update,final,digest. the actual crunching. the main characters, honestly π - Digest state serialization β
serialize,deserialize. saving and loading the lil guy's soul β¨ - Digest parameter descriptors β
gettable_params. "what can you tell me about yourself" energy π - Digest operation parameter descriptors β
gettable_ctx_params,settable_ctx_params. "what can I read/write on a live operation" π¦ - Digest parameters β
get_params. the static stats, not tied to any one context πΈ - Digest operation parameters β
set_ctx_params,get_ctx_params. the live, per-operation knobs π
and that's where part 1 leaves us, bestie. the rest is coming β don't go anywhere π
π DESCRIPTION π
okay so bestie, this whole page is for provider authors β the devs writing providers, iykyk. if you're not one, go peek at provider(7) first, it'll catch you up. π«Ά
The DIGEST operation is how providers implement digest algorithms and drop them into the hands of applications through the API functions EVP_DigestInit_ex(3), EVP_DigestUpdate(3) and EVP_DigestFinal(3) (plus all their little related function friends).
Every "function" we gossip about here is actually passed as a function pointer, dying back and forth between libcrypto and the provider inside OSSL_DISPATCH(3) arrays, which ride in via OSSL_ALGORITHM(3) arrays that the provider's provider_query_operation() function hands back (scroll to "Provider Functions" in provider-base(7) for the tea).
Every one of these "functions" has a matching function type definition named OSSL_FUNC_{name}_fn, and a lil helper function that fetches the function pointer out of an OSSL_DISPATCH(3) element, named OSSL_FUNC_{name}. for example, the "function" OSSL_FUNC_digest_newctx() comes with exactly these:
typedef void *(OSSL_FUNC_digest_newctx_fn)(void *provctx);
static ossl_inline OSSL_FUNC_digest_newctx_fn
OSSL_FUNC_digest_newctx(const OSSL_DISPATCH *opf);
OSSL_DISPATCH(3) arrays are indexed by numbers, and those numbers live as macros in openssl-core_dispatch.h(7), like this:
OSSL_FUNC_digest_newctx OSSL_FUNC_DIGEST_NEWCTX
OSSL_FUNC_digest_freectx OSSL_FUNC_DIGEST_FREECTX
OSSL_FUNC_digest_dupctx OSSL_FUNC_DIGEST_DUPCTX
OSSL_FUNC_digest_copyctx OSSL_FUNC_DIGEST_COPYCTX
OSSL_FUNC_digest_init OSSL_FUNC_DIGEST_INIT
OSSL_FUNC_digest_update OSSL_FUNC_DIGEST_UPDATE
OSSL_FUNC_digest_final OSSL_FUNC_DIGEST_FINAL
OSSL_FUNC_digest_digest OSSL_FUNC_DIGEST_DIGEST
OSSL_FUNC_digest_serialize OSSL_FUNC_DIGEST_SERIALIZE
OSSL_FUNC_digest_deserialize OSSL_FUNC_DIGEST_DESERIALIZE
OSSL_FUNC_digest_get_params OSSL_FUNC_DIGEST_GET_PARAMS
OSSL_FUNC_digest_get_ctx_params OSSL_FUNC_DIGEST_GET_CTX_PARAMS
OSSL_FUNC_digest_set_ctx_params OSSL_FUNC_DIGEST_SET_CTX_PARAMS
OSSL_FUNC_digest_gettable_params OSSL_FUNC_DIGEST_GETTABLE_PARAMS
OSSL_FUNC_digest_gettable_ctx_params OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS
OSSL_FUNC_digest_settable_ctx_params OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS
a digest algorithm implementation doesn't have to implement all of these, bestie. but to actually be usable, you need all or none of OSSL_FUNC_digest_newctx, OSSL_FUNC_digest_freectx, OSSL_FUNC_digest_init, OSSL_FUNC_digest_update, OSSL_FUNC_digest_final and OSSL_FUNC_digest_get_params. everything else? optional, do what you want. π
π Context Management Functions π
OSSL_FUNC_digest_newctx()β should create and return a pointer to a provider-side structure that holds context info during a digest operation. that pointer gets passed back into a bunch of the other digest operation function calls. theprovctxparameter is the provider context made during provider initialisation (seeprovider(7)).OSSL_FUNC_digest_freectx()β gets handed a pointer to the provider-side digest context in thedctxparameter. this function should free every resource tied to that context.OSSL_FUNC_digest_dupctx()β should duplicate the provider-side digest context in thedctxparameter and return the duplicate copy. β¨OSSL_FUNC_digest_copyctx()β should copy the provider-side digest context in thevinctxparameter over to thevoutctxparameter, which is, like, another provider-side context. theOSSL_FUNC_digest_copyctxfunction gets used inside theEVP_MD_CTX_copy_exfunction to speed up HMAC operations in the PBKDF2. this one's optional, anddupctxwill be used if there's noEVP_MD_CTX_copy_exfunction.
πΈ Digest Generation Functions πΈ
OSSL_FUNC_digest_init()β initialises a digest operation given a freshly created provider-side digest context in thedctxparameter. theparams, if it's notNULL, should be set on the context in a way similar to usingOSSL_FUNC_digest_set_ctx_params().OSSL_FUNC_digest_update()β gets called to feed in data to be digested, as part of a digest operation that was already initialised. thedctxparameter holds a pointer to a previously initialised provider-side context.OSSL_FUNC_digest_update()should digestinlbytes of data sitting at the locationinpoints to. and it's totally fine to callOSSL_FUNC_digest_update()multiple times for one single digest operation. π₯OSSL_FUNC_digest_final()β generates a digest that was started via earlierOSSL_FUNC_digest_init()andOSSL_FUNC_digest_update()calls. thedctxparameter holds a pointer to the provider-side context. the digest should be written to*outand the length of the digest to*outl. and fr, the digest must not exceedoutszbytes.OSSL_FUNC_digest_digest()β this one's a "oneshot" digest function, no cap. no provider-side digest context gets used at all. instead, the provider context created during provider initialisation is passed in theprovctxparameter (seeprovider(7)).inlbytes atinshould be digested, and the result stored atout. the length of the digest goes into*outl, which should not exceedoutszbytes.
π¦ Digest State Serialization Functions π¦
OSSL_FUNC_digest_serialize() serializes the state of the digest context dctx. if out is NULL, then the maximum necessary size for the output buffer gets written to *outl. if out is not NULL, then *outl is assumed to already contain the length of the out buffer. if the call succeeds, the serialized data is written to out and however much data was written gets stored in *outl. β¨
OSSL_FUNC_digest_deserialize() deserializes the data from in, of size inlen, into the digest context dctx. the context dctx should be initialized before you call this function. after a successful deserialization, the context is ready to be used for any subsequent digest operations. π
the content of the state and its validity (over time, process lifetime, etc.) are completely in the control of the provider. the docs for each provider should state exactly what guarantees it can offer when it comes to recovering the state of a serialized blob.
π Digest Parameters π
peep OSSL_PARAM(3) for more details on the parameters structure these functions use.
OSSL_FUNC_digest_get_params()β gets the details of the algorithm implementation and stores them inparams.OSSL_FUNC_digest_set_ctx_params()β sets digest operation parameters for the provider-side digest contextdctxtoparams. any parameter settings are additional to whatever was previously set. passingNULLforparamsshould return true.OSSL_FUNC_digest_get_ctx_params()β gets digest operation details from the given provider-side digest contextdctxand stores them inparams. passingNULLforparamsshould return true.OSSL_FUNC_digest_gettable_params()β returns a constantOSSL_PARAM(3)array holding descriptors of the parameters thatOSSL_FUNC_digest_get_params()can handle.OSSL_FUNC_digest_gettable_ctx_params()andOSSL_FUNC_digest_settable_ctx_params()β both return constantOSSL_PARAM(3)arrays as descriptors of the parameters thatOSSL_FUNC_digest_get_ctx_params()andOSSL_FUNC_digest_set_ctx_params()can handle, respectively. the array is based on the current state of the provider-side context ifdctxis notNULL, and on the provider-side algorithmprovctxotherwise.
the parameters currently recognised by built-in digests with this function are as follows. heads up: not all parameters are relevant to, or understood by, all digests. π
"blocksize"(OSSL_DIGEST_PARAM_BLOCK_SIZE)<unsigned integer>β the digest block size. the length of the"blocksize"parameter should not exceed that of asize_t."size"(OSSL_DIGEST_PARAM_SIZE)<unsigned integer>β the digest output size. the length of the"size"parameter should not exceed that of asize_t."flags"(OSSL_DIGEST_PARAM_FLAGS)<unsigned integer>β diverse flags describing exceptional behaviour for the digest:EVP_MD_FLAG_ONESHOTβ this digest method can only handle one block of input.EVP_MD_FLAG_XOFβ this digest method is an extensible-output function (XOF).EVP_MD_FLAG_DIGALGID_NULLβ when setting up a DigestAlgorithmIdentifier, this flag will have the parameter set toNULLby default. use this for PKCS#1. note: if combined withEVP_MD_FLAG_DIGALGID_ABSENT, the latter will override.EVP_MD_FLAG_DIGALGID_ABSENTβ when setting up a DigestAlgorithmIdentifier, this flag will have the parameter left absent by default. note: if combined withEVP_MD_FLAG_DIGALGID_NULL, the latter will be overridden.EVP_MD_FLAG_DIGALGID_CUSTOMβ custom DigestAlgorithmIdentifier handling via ctrl, withEVP_MD_FLAG_DIGALGID_ABSENTas default. note: if combined withEVP_MD_FLAG_DIGALGID_NULL, the latter will be overridden. currently unused.
the length of the "flags" parameter should equal that of an unsigned long int.
π Digest Context Parameters π
OSSL_FUNC_digest_set_ctx_params() sets digest parameters associated with the given provider-side digest context dctx to params. any parameter settings are additional to any that were previously set. see OSSL_PARAM(3) for further details on the parameters structure. π
OSSL_FUNC_digest_get_ctx_params() gets details of the currently set parameter values associated with the give provider-side digest context dctx and stores them in params. see OSSL_PARAM(3) for further details on the parameters structure.
the OpenSSL FIPS provider supports the following gettable context parameter:
"fips-indicator"(OSSL_DIGEST_PARAM_FIPS_APPROVED_INDICATOR)<integer>β returns1if the operation is FIPS approved, or0otherwise. see "FIPS indicators" infips_module(7)for more information. β
β RETURN VALUES β
OSSL_FUNC_digest_newctx() and OSSL_FUNC_digest_dupctx() should return the newly created provider-side digest context, or NULL on failure. π
OSSL_FUNC_digest_init(), OSSL_FUNC_digest_update(), OSSL_FUNC_digest_final(), OSSL_FUNC_digest_digest(), OSSL_FUNC_digest_get_params(), OSSL_FUNC_digest_set_ctx_params(), OSSL_FUNC_digest_get_ctx_params(), OSSL_FUNC_digest_serialize(), and OSSL_FUNC_digest_deserialize() should return 1 for success or 0 on error. periodt.
OSSL_FUNC_digest_size() should return the digest size.
OSSL_FUNC_digest_block_size() should return the block size of the underlying digest algorithm.
π BUGS π
okay so this is a real one, bestie: theEVP_Q_digest(),EVP_Digest()andEVP_DigestFinal_ex()API calls do not expect the digest size to be larger thanEVP_MAX_MD_SIZE. any algorithm that produces bigger digests is literally unusable with those API calls. π no cap.
π SEE ALSO β the bestie recommendations β¨
okay so if this page ate and you want more, these are the icons you should also be reading, fr fr:
provider(7)OSSL_PROVIDER-FIPS(7)OSSL_PROVIDER-default(7)OSSL_PROVIDER-legacy(7)EVP_MD-common(7)EVP_MD-BLAKE2(7)EVP_MD-MD2(7)EVP_MD-MD4(7)EVP_MD-MD5(7)EVP_MD-MD5-SHA1(7)EVP_MD-MDC2(7)EVP_MD-RIPEMD160(7)EVP_MD-SHA1(7)EVP_MD-SHA2(7)EVP_MD-SHA3(7)EVP_MD-KECCAK(7)EVP_MD-SHAKE(7)EVP_MD-SM3(7)EVP_MD-WHIRLPOOL(7)EVP_MD-NULL(7)EVP_MD-ML-DSA-MU(7)life_cycle-digest(7)EVP_DigestInit(3)
(yes literally all of them, go read, it's giving β¨ research era β¨)
π HISTORY β the lore π
- the whole provider DIGEST interface? introduced in OpenSSL 3.0. iconic debut, no notes.
OSSL_FUNC_digest_copyctx()slid in later, in the 3.5 version. late arrival but so valid.- the
"fips-indicator"context parameter? that's an OpenSSL 4.0 addition. newest baby in the family πΌ
Β©οΈ COPYRIGHT β the receipts π
Copyright 2019-2026 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>.
okay bestie that's the whole page, we made it, you're officially a digest provider expert now π π
this fine piece of documentation is straight from OpenSSL 4.0.3, dated 2026-09-29, and it lives at the manpage address PROVIDER-DIGEST(7SSL). go forth and hash responsibly π¦β¨πΈ
π¦ where this page comes from
- ubuntu stonking: openssl 4.0.3-1ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms