EVP_SIGNINIT(3)

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

πŸ’– EVP_SIGNINIT(3) β€” Library Functions Manual πŸ’–

okay bestie, welcome to the Library Functions Manual page for EVP_SignInit_ex, EVP_SignUpdate, EVP_SignFinal and EVP_SignInit β€” the whole little friend group of EVP signing functions 🫢 pull up a chair, we're signing things today.


✨ NAME ✨

EVP_SignInit_ex, EVP_SignUpdate, EVP_SignFinal, EVP_SignInit β€” the EVP signing functions, no cap πŸ’…


🌸 SYNOPSIS 🌸

calling all libcrypto girlies β€” library β€œlibcrypto”

#include <openssl/evp.h>

int
EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine);

int
EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt);

int
EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sig, unsigned int *s,
    EVP_PKEY *pkey);

void
EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type);

πŸ¦‹ DESCRIPTION πŸ¦‹

so the EVP signature routines are literally a high-level interface to digital signatures. main character energy only, we don't do low-level here πŸ’…

EVP_SignInit_ex() sets up the signing context ctx to use the digest type. but listen β€” before you call this, you gotta obtain ctx from EVP_MD_CTX_new(3) or call EVP_MD_CTX_reset(3) on it first, that's the vibe check. the engine argument is always ignored (yes, always, not even kidding) and passing NULL is the recommended move ✨

EVP_SignUpdate() hashes cnt bytes of data at d into the signature context ctx. and the slay part? you can call this several times on the same ctx to include additional data β€” feed it data in lil chunks, it eats πŸ“

EVP_SignFinal() signs the data in ctx using the private key pkey and places the signature in sig. important: sig must be at least EVP_PKEY_size(3) bytes big, don't be out here with a tiny buffer πŸ™ˆ s is an OUT parameter, and it's not used as an IN parameter β€” so don't put anything in it expecting it to matter. the number of bytes of data written (i.e. the length of the signature) gets written to the integer at s. and at most EVP_PKEY_size(3) bytes will be written. periodt.

EVP_SignInit() initializes a signing context ctx to use the default implementation of digest type.

real talk though: the EVP interface to digital signatures should almost always be used in preference to the low-level interfaces. why? because your code becomes transparent to the algorithm used and is much more flexible β€” iconic behaviour only πŸ‘‘

okay this next bit is the detail nobody clocks: the call to EVP_SignFinal() internally finalizes a copy of the digest context. which means calls to EVP_SignUpdate() and EVP_SignFinal() can be made later to digest and sign additional data. so you're not locked out after the first final β€” love that for you πŸŽ€

⚠️ but bestie, since only a copy of the digest context is ever finalized, you must clean up the context after use by calling EVP_MD_CTX_free(3) β€” otherwise a memory leak happens and we do NOT want that energy 😭

and one more thing: EVP_SignInit_ex(), EVP_SignUpdate(), and EVP_SignInit() are implemented as macros. iykyk πŸ’…


⭐ RETURN VALUES ⭐

  • EVP_SignInit_ex(), EVP_SignUpdate(), and EVP_SignFinal() return 1 for success and 0 for failure. simple as that, no plot twist 🌈

if you need the error codes, get them with ERR_get_error(3) β€” that's where the receipts live 🧾


πŸŽ€ SEE ALSO πŸŽ€

go read those next, you'll thank me πŸ’–


πŸ‘‘ HISTORY πŸ‘‘

EVP_SignInit(), EVP_SignUpdate(), and EVP_SignFinal() first appeared in SSLeay 0.5.1 and have been available since OpenBSD 2.4. vintage icons fr fr πŸ•°οΈ

EVP_SignInit_ex() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.2. the newer sibling, also iconic 🌟


πŸ’€ BUGS πŸ’€

  • okay so older versions of this documentation wrongly stated that calls to EVP_SignUpdate() could not be made after calling EVP_SignFinal(). that was a lie, we've moved on πŸ™ˆ
  • because the private key is passed in the call to EVP_SignFinal(), any error relating to the private key (for example an unsuitable key and digest combination) will not be indicated until after potentially large amounts of data have been passed through EVP_SignUpdate(). so you could push a whole lotta data through and then find out πŸ’€
  • it is not possible to change the signing parameters using these functions. nope. can't do it.
πŸ’‘ good news though β€” the previous two bugs are fixed in the newer EVP_DigestSign* function. slay for progress πŸ¦‹

and that's the whole page bestie!! mwah πŸ’‹ this little gem lives in the Debian build of the page, dated June 8, 2025, filed under EVP_SIGNINIT(3) β€” go sign something cute, and don't forget to EVP_MD_CTX_free(3) 🫢✨

πŸ“¦ where this page comes from