LIBRESSL-EVP_PKEY_CTX_SET_TLS1_PRF_MD(3)
π EVP_PKEY_CTX_SET_TLS1_PRF_MD(3) β the TLS PRF key derivation girlies β¨
okay so bestie, this is a page from the libcrypto manual and honestly? it's a little niche but it slaps once you get it. we're talking TLS PRF key derivation β the thing that turns your secret into actual key material. no cap, it's kind of the whole vibe behind TLS 1.0/1.1 keying. π
β¨ NAME β¨
EVP_PKEY_CTX_set_tls1_prf_md, EVP_PKEY_CTX_set1_tls1_prf_secret, EVP_PKEY_CTX_add1_tls1_prf_seed β the TLS PRF key derivation algorithm, aka the three functions you need to make it happen π¦
πΈ SYNOPSIS πΈ
first up, the library and the headers you gotta pull in (yes both of them, don't @ me):
library βlibcryptoβ
#include <openssl/evp.h>
#include <openssl/kdf.h>
and here are the three icons themselves, exactly as they are:
int
EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *pctx, const EVP_MD *md);
int
EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx,
unsigned char *sec, int seclen);
int
EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *pctx, unsigned char *seed,
int seedlen);
π DESCRIPTION π
So the EVP_PKEY_TLS1_PRF algorithm implements the PRF key derivation function for TLS. It's giving "no thoughts head empty" in the best way β it has no associated private key and only implements key derivation using EVP_PKEY_derive(3). That's it. That's the whole job. π
EVP_PKEY_set_tls1_prf_md() sets the message digest associated with the TLS PRF. And here's the cute special case: EVP_md5_sha1(3) gets treated specially β it uses the PRF algorithm with both MD5 and SHA-1, exactly like TLS 1.0 and 1.1 did. iconic behavior, honestly. π
EVP_PKEY_CTX_set_tls1_prf_secret() sets the secret value of the TLS PRF to seclen bytes of the buffer sec. Heads up: any existing secret value is replaced, and any seed is reset. so it's a clean slate moment, periodt. π
EVP_PKEY_CTX_add1_tls1_prf_seed() sets the seed to seedlen bytes of seed. And if a seed is already set? it gets appended to the existing value. it's additive, it's generous, it's main character energy. π«Ά
π STRING CTRLS π
the TLS PRF also supports string based control operations using EVP_PKEY_CTX_ctrl_str(3). here's the rundown of the type params, bestie:
- the type parameter
"md"uses the supplied value as the name of the digest algorithm to use. - the type parameters
"secret"and"seed"use the supplied value parameter as a secret or seed value. - the names
"hexsecret"and"hexseed"are similar, except they take a hex string which gets converted to binary. hex girlies rise π§
π₯ NOTES π₯
- All these functions are implemented as macros. (yes, macros. don't come for me, that's just how it is.)
- A context for the TLS PRF can be obtained by calling:
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
- The digest, secret value and seed must be set before a key is derived, or an error occurs. no skipping steps, babe π
- The total length of all seeds cannot exceed 1024 bytes in length β and like, that should be more than enough for any normal use of the TLS PRF. fr fr.
- The output length of the PRF is specified by the
lengthparameter in theEVP_PKEY_derive(3)function. Since the output length is variable, setting the buffer toNULLis not meaningful for the TLS PRF. so don't do that π
β RETURN VALUES β
All these functions return 1 for success and 0 or a negative value for failure. And specifically: a return value of -2 indicates the operation is not supported by the public key algorithm. ok so -2 is the "this isn't my thing" number, noted. π
πΈ EXAMPLES πΈ
this example derives 10 bytes using SHA-256 with the secret key "secret" and seed value "seed". look at her go:
EVP_PKEY_CTX *pctx;
unsigned char out[10];
size_t outlen = sizeof(out);
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
if (EVP_PKEY_derive_init(pctx) <= 0)
/* Error */
if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_sha256()) <= 0)
/* Error */
if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, "secret", 6) <= 0)
/* Error */
if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, "seed", 4) <= 0)
/* Error */
if (EVP_PKEY_derive(pctx, out, &outlen) <= 0)
/* Error */
π¦ SEE ALSO π¦
go read these next, iykyk π
π HISTORY π
These functions first appeared in OpenSSL 1.1.0 and have been available since OpenBSD 7.6. glow up timeline honestly β¨
and that's the page, bestie! this one came from the Debian crew, dated June 8, 2025, under the manual name EVP_PKEY_CTX_SET_TLS1_PRF_MD(3) β mwah, go derive some keys responsibly ππ
π¦ where this page comes from
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2016 The OpenSSL Project. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms