EVP_CIPHER_CTX_CTRL(3)

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

πŸ’… EVP_CIPHER_CTX_CTRL(3) β€” configure EVP cipher contexts

Ok so bestie, this one is from the Library Functions Manual and it's literally the whole "tweak your cipher context" situation, all in one place. Pull it in with libcrypto and you're set:

#include <openssl/evp.h>

✨ SYNOPSIS ✨

The whole squad, in signature form β€” copy these exactly, no cap:

int
EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);

int
EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding);

int
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);

int
EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);

int
EVP_CIPHER_key_length(const EVP_CIPHER *e);

int
EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);

int
EVP_CIPHER_iv_length(const EVP_CIPHER *e);

int
EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv,
    size_t len);

int
EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv,
    size_t len);

πŸŽ€ DESCRIPTION πŸŽ€

🧚 EVP_CIPHER_CTX_ctrl()

This one is your little control-freak function for cipher-specific params β€” it lets you both find out and set all those funky per-cipher settings. Right now the only thing you can actually set with it is the RC2 effective key length β€” go peek at EVP_rc2_cbc(3) for the deets, iykyk.

🩷 EVP_CIPHER_CTX_set_padding()

Turns padding on or off. The vibe check here: you gotta call it after the context has been set up for encrypting or decrypting β€” so after EVP_EncryptInit_ex(3), EVP_DecryptInit_ex(3), or EVP_CipherInit_ex(3). Like, order matters bestie.

By default, encryption operations get padded using standard block padding, and that padding gets checked and removed on the way back out when you decrypt. 🫢

But β€” and this is the part that bites β€” if the padding parameter is zero, then no padding happens at all, and the total amount of data you encrypt or decrypt must be a multiple of the block size, or an error happens. Periodt.

πŸ”‘ EVP_CIPHER_CTX_set_key_length()

Sets the key length of the cipher ctx. And if the cipher is a fixed-length cipher? Then trying to set the key length to anything other than that fixed value is just straight-up an error. No negotiating. πŸ’…

πŸ¦‹ EVP_CIPHER_CTX_key_length() and EVP_CIPHER_key_length()

These two hand you the key length of a cipher when you pass in an EVP_CIPHER_CTX or an EVP_CIPHER structure respectively. The constant EVP_MAX_KEY_LENGTH is the max key length for all ciphers, iconic.

Note: even though EVP_CIPHER_key_length() is fixed for any given cipher, the value of EVP_CIPHER_CTX_key_length() can actually be different for variable-key-length ciphers. So don't assume they match, ngl.

🌸 EVP_CIPHER_CTX_iv_length() and EVP_CIPHER_iv_length()

Same energy, but for the IV length β€” pass an EVP_CIPHER_CTX or an EVP_CIPHER and get the length back. They'll return zero if the cipher doesn't use an IV at all.

EVP_CIPHER_CTX_iv_length() can fail and return -1 though, so watch for that. The constant EVP_MAX_IV_LENGTH is the max IV length across all ciphers. ✨

πŸ“ EVP_CIPHER_CTX_set_iv() and EVP_CIPHER_CTX_get_iv()

Set and retrieve the IV for an EVP_CIPHER_CTX respectively β€” like the matching bestie bracelets of IV handling.

Big one: in both cases, the IV length you specify must exactly equal the expected IV length for that context, i.e. whatever EVP_CIPHER_CTX_iv_length() gives you back. Not "close enough." Exact.

πŸ‘‘ RETURN VALUES πŸ‘‘

  • EVP_CIPHER_CTX_ctrl() β€” returns 1 for success or 0 for failure. Some implementations may return negative values for certain errors, so don't be shocked.
  • EVP_CIPHER_CTX_set_padding() β€” always returns 1. Always. Iconic consistency.
  • EVP_CIPHER_CTX_set_key_length(), EVP_CIPHER_CTX_set_iv(), and EVP_CIPHER_CTX_get_iv() β€” return 1 for success or 0 for failure.
  • EVP_CIPHER_CTX_key_length() and EVP_CIPHER_key_length() β€” return the key length.
  • EVP_CIPHER_CTX_iv_length() and EVP_CIPHER_iv_length() β€” return the IV length, or zero if the cipher doesn't use an IV. And EVP_CIPHER_CTX_iv_length() can fail and return -1.

🌈 SEE ALSO 🌈

evp(3), EVP_CIPHER_nid(3), EVP_EncryptInit(3)


⭐ HISTORY ⭐

  • EVP_CIPHER_CTX_key_length(), EVP_CIPHER_key_length(), EVP_CIPHER_CTX_iv_length(), and EVP_CIPHER_iv_length() first appeared in SSLeay 0.6.5 and have been available since OpenBSD 2.4. Ancient. Vintage. Iconic.
  • EVP_CIPHER_CTX_ctrl() and EVP_CIPHER_CTX_set_key_length() first appeared in OpenSSL 0.9.6 and have been available since OpenBSD 2.9.
  • EVP_CIPHER_CTX_set_padding() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.2.
  • EVP_CIPHER_CTX_set_iv() and EVP_CIPHER_CTX_get_iv() first appeared in LibreSSL 2.8.1 and have been available since OpenBSD 6.4. The babies of the group 🫢

πŸ’€ BUGS πŸ’€

So EVP_MAX_KEY_LENGTH and EVP_MAX_IV_LENGTH only refer to the internal ciphers with default key lengths. If custom ciphers exceed those values, the results are unpredictable β€” like genuinely, nobody knows what happens, and that's not a vibe.

Why? Because it's become standard practice to define a generic key as a fixed unsigned char array containing EVP_MAX_KEY_LENGTH bytes. So yeah, that's the whole situation. πŸ™ˆ


πŸ’– that's the page, bestie πŸ’– Straight from Debian, dated June 8, 2025 β€” go forth and configure those cipher contexts responsibly βœ¨πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from