EVP_BYTESTOKEY(3)

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

okay so this is the EVP_BYTESTOKEY(3) page from the Library Functions Manual, and we're about to make key-and-IV derivation make sense, bestie πŸ’– Buckle up πŸŽ€


πŸ’– NAME πŸ’–

EVP_BytesToKey β€” password based encryption routine ✨

✨ SYNOPSIS ✨

library β€œlibcrypto”
#include <openssl/evp.h>

int
EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
    const unsigned char *salt, const unsigned char *data, int datal,
    int count, unsigned char *key, unsigned char *iv);

πŸ¦‹ DESCRIPTION πŸ¦‹

EVP_BytesToKey() is literally the β€œderive a key and IV from these parameters” situation. Here's the cast, bestie:

  • type β€” the cipher to derive the key and IV for πŸ’…
  • md β€” the message digest to use 🧚
  • salt β€” used as a salt in the derivation. It should point to a buffer containing PKCS5_SALT_LEN = 8 bytes, or be NULL if no salt is used 🌸
  • data β€” a buffer containing datal bytes, and it's used to derive the keying data πŸ“
  • count β€” the iteration count to use πŸ”
  • key and iv β€” the derived key and IV get written here, respectively πŸ‘‘

A typical application of this function is deriving keying material for an encryption algorithm from a password in the data parameter. Password-to-key pipeline, iconic πŸ’–

Increasing the count parameter slows down the algorithm, which makes it harder for an attacker to perform a brute force attack using a large number of candidate passwords. Slow it down so the attackers have a worse time, periodt πŸ”₯

Compatibility tea β˜•: if the total key and IV length is less than the digest length and MD5 is used, then the derivation algorithm is compatible with PKCS#5 v1.5. Otherwise, a non-standard extension is used to derive the extra data. Yeah, it's giving legacy behavior.

🚨 Bestie, newer applications should use more standard algorithms such as PBKDF2 as defined in PKCS#5v2.1 for key derivation. Don't make this your main character unless you have to.

🌈 KEY DERIVATION ALGORITHM 🌈

The key and IV are derived by concatenating D_1, D_2, etc. until enough data is available for the key and IV. D_i is defined recursively as:

D_i = HASH^count(D_(i-1) || data || salt)

where || denotes concatenation, D_0 is empty, HASH is the digest algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is HASH(HASH(data)), and so on. Recursive little icon πŸŒ€

The initial bytes are used for the key and the subsequent bytes for the IV. That's the split, bestie βœ‚οΈ

πŸ’œ RETURN VALUES πŸ’œ

If data is NULL, EVP_BytesToKey() returns the number of bytes needed to store the derived key. Otherwise, EVP_BytesToKey() returns the size of the derived key in bytes or 0 on error. So: NULL data = β€œhow much room do I need?” vibe; normal data = actual derived-key size, or 0 if something went wrong 😭

πŸ”Ž SEE ALSO πŸ”Ž

🫢 HISTORY 🫢

EVP_BytesToKey() first appeared in SSLeay 0.5.1 and has been available since OpenBSD 2.4. Ancestor energy πŸ‘‘


k bye β€” this page is from Debian, dated June 8, 2025. Stay hydrated and keep your keys cute, bestie πŸ’–βœ¨

πŸ“¦ where this page comes from