EVP_MD_CTX_CTRL(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’– EVP_MD_CTX_CTRL πŸ’–

okay so this is the EVP_MD_CTX_CTRL(3) page from the library functions manual, bestie β€” it's all about wrangling EVP message digest contexts, and honestly it's a whole little friend group of functions. Let's get into it 🫢


✨ NAME ✨

EVP_MD_CTX_ctrl, EVP_MD_CTX_set_flags, EVP_MD_CTX_clear_flags, EVP_MD_CTX_test_flags, EVP_MD_CTX_pkey_ctx, EVP_MD_CTX_set_pkey_ctx, EVP_MD_CTX_md_data β€” configure EVP message digest contexts 🌸


πŸŽ€ SYNOPSIS πŸŽ€

the library is libcrypto, and you get all of this from:

#include <openssl/evp.h>

and here are the signatures, literally verbatim, no cap:

int
EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int command, int p1, void* p2);

void
EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);

void
EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);

int
EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);

EVP_PKEY_CTX *
EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);

void
EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx);

void *
EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);

πŸ’… DESCRIPTION πŸ’…

the ctrl one πŸŽ›οΈ

EVP_MD_CTX_ctrl() performs the digest-specific control command with the command-specific arguments p1 and p2 on ctx. Important: ctx needs to already be set up with EVP_DigestInit_ex(3) before you call this. Other restrictions may apply depending on the control command and the digest implementation β€” so like, read the room, iykyk.

If the command is EVP_MD_CTRL_MICALG, p1 is ignored and p2 is an output argument of the type char **p2. A string specifying the digest Message Integrity Check algorithm gets allocated, and a pointer to this string is returned in *p2. Bestie, listen: it is the responsibility of the caller to free(3) *p2 when it is no longer needed. Don't leave her hanging 😭. This command is used by SMIME_write_CMS(3) and SMIME_write_PKCS7(3) when creating S/MIME multipart/signed messages as specified in RFC 3851.

the flags girlies 🚩

EVP_MD_CTX_set_flags() sets and EVP_MD_CTX_clear_flags() clears all the flag bits in ctx that are set in the flags argument. EVP_MD_CTX_test_flags() tests which of the flag bits that are set in the flags argument are also set in ctx. Possible flag bits are:

  • EVP_MD_CTX_FLAG_NO_INIT β€” Instruct EVP_DigestInit_ex(3) and functions calling it not to initialise the internal data that is specific to the digest method and its implementation.
  • EVP_MD_CTX_FLAG_ONESHOT β€” Instruct the digest to optimize for one update only, if possible. For digest algorithms built into the library, this flag usually has no effect. it's giving decorative, honestly πŸ’€

the pkey ctx duo πŸ”‘

EVP_MD_CTX_pkey_ctx() returns the EVP_PKEY_CTX assigned to ctx. The returned pointer should not be freed by the caller β€” she's not yours, don't touch her πŸ™ˆ.

EVP_MD_CTX_set_pkey_ctx() assigns pctx to ctx. This is normally used to provide a customized EVP_PKEY_CTX to EVP_DigestSignInit(3) or EVP_DigestVerifyInit(3). The caller retains ownership of the pctx passed to this function and is responsible for freeing it when it is no longer needed.

⚠️ Okay this next bit is the messy part, pay attention: if the ctx already contains a EVP_PKEY_CTX when this function is called, that old EVP_PKEY_CTX is freed if it was created internally β€” but if it was also installed with EVP_MD_CTX_set_pkey_ctx(), the pointer to the old EVP_PKEY_CTX is merely replaced by the new pointer, and ownership of the old EVP_PKEY_CTX remains with the previous caller. So like… know whose EVP_PKEY_CTX is whose. fr fr.

Passing a NULL pointer for the pctx argument is also allowed. In that case, any EVP_PKEY_CTX already assigned to ctx is dissociated from it as described above, but no new EVP_PKEY_CTX is assigned. just… unassigning. slay.

the md_data one 🧚

EVP_MD_CTX_md_data() returns the digest method private data of ctx. The space is allocated with a size determined at compile time. The size is not exposed by an API β€” so no, you can't ask her how big she is, the API said no 🌈.


⭐ RETURN VALUES ⭐

  • EVP_MD_CTX_ctrl() returns 1 for success or 0 for failure.
  • EVP_MD_CTX_test_flags() returns the bitwise OR of the flags argument and the flags set in ctx.
  • EVP_MD_CTX_pkey_ctx() and EVP_MD_CTX_md_data() return pointers to storage owned by ctx.

πŸ¦‹ SEE ALSO πŸ¦‹

evp(3), EVP_DigestInit(3), EVP_MD_nid(3) β€” go read those too, bestie, they're all connected ✨


πŸ‘‘ HISTORY πŸ‘‘

EVP_MD_CTX_set_flags(), EVP_MD_CTX_clear_flags(), and EVP_MD_CTX_test_flags() first appeared in OpenSSL 0.9.7 and have been available since OpenBSD 3.2.

EVP_MD_CTX_ctrl() first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 5.7.

EVP_MD_CTX_pkey_ctx() and EVP_MD_CTX_md_data() first appeared in OpenSSL 1.1.0 and EVP_MD_CTX_set_pkey_ctx() in OpenSSL 1.1.1. These functions have been available since OpenBSD 7.1. the way that timeline ate, honestly πŸ”₯


and that's the whole page, bestie πŸ’œ β€” this one came from Debian, dated June 11, 2025, and it's the EVP_MD_CTX_CTRL(3) manual page. go forth and configure your digest contexts responsibly πŸŽ€βœ¨

πŸ“¦ where this page comes from