EVP_PKEY_DERIVE(3SSL)
β¨ EVP_PKEY_DERIVE β¨ (that's the EVP_PKEY_DERIVE(3SSL) page bestie, OpenSSL's little shared-secret-maker)
okay so picture this: you and your peer have keys, you wanna agree on a secret without shouting it across the network β that's a shared secret derivation and this whole page is the group chat where that happens π
πΈ NAME πΈ
EVP_PKEY_derive_init, EVP_PKEY_derive_init_ex, EVP_PKEY_derive_set_peer_ex, EVP_PKEY_derive_set_peer, EVP_PKEY_derive, EVP_PKEY_derive_SKEY β the icons that derive a public key algorithm shared secret π
π SYNOPSIS π
#include <openssl/evp.h>
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
int validate_peer);
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
EVP_SKEY *EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEYMGMT *mgmt,
const char *key_type, const char *propquery,
size_t keylen, const OSSL_PARAM params[]);
π DESCRIPTION π
So like, EVP_PKEY_derive_init() gets a public key algorithm context ctx all set up and ready for shared secret derivation, using whichever algorithm the context was born with back when you made it with EVP_PKEY_CTX_new(3) or one of its lil variants. That algorithm is what's used to implicitly fetch an EVP_KEYEXCH method β and if you're like "bestie what is an implicit fetch??" then go read "Implicit fetch" in provider(7), it's all explained there fr fr π
Then EVP_PKEY_derive_init_ex() is literally the same thing as EVP_PKEY_derive_init(), EXCEPT it also sets the parameters you pass in params on the context before it hands control back. cute right β¨
EVP_PKEY_derive_set_peer_ex() is the one that sets the peer key β and normally that's gonna be a public key. And validate_peer? If that value is non zero, the public key gets validated. non-zero = yes please check it π΅οΈβοΈ
EVP_PKEY_derive_set_peer() is just EVP_PKEY_derive_set_peer_ex() but with validate_peer set to 1. same vibes, less typing π«Ά
EVP_PKEY_derive() is the main event β it derives a shared secret using ctx. And here's the two-mode thing you gotta know:
- if
keyisNULL, then the maximum size of the output buffer gets written into thekeylenparameter (this is your "how much room do I need, bestie" call) - if
keyis NOTNULL, then before the callkeylenshould already contain the length of your key buffer, and if the call works out, the shared secret gets written intokeyand the amount of data actually written goes intokeylenπ₯
EVP_PKEY_derive_SKEY() is EVP_PKEY_derive() coded slightly differently: instead of dumping bytes into a buffer, it hands you back an EVP_SKEY object that stores the opaque data for the derived key. Now β if you pass an EVP_SKEYMGMT argument, it gets explicitly used for the EVP_SKEY creation, periodt. Otherwise the EVP_SKEYMGMT object used for EVP_SKEY gets fetched according to skeymgmtname and propquery. And if skeymgmtname is NULL, it just assumes the name matching the key exchange method name. slay, no notes π
π NOTES π
Once EVP_PKEY_derive_init() has been called, you can do algorithm specific control operations to set up whatever parameters the operation needs. go off, set your params π
Also iconic: EVP_PKEY_derive() can be called more than once on the same context, as long as you're doing several operations with the same parameters. reuse is self-care β»οΈ
lowkey a reminder that the synopsis useskey_typeandpropquerywhile the description talks aboutskeymgmtnameandpropqueryβ that's just how the page is written, don't come for me, I'm keeping it exactly as-is π
β RETURN VALUES β
EVP_PKEY_derive_init()andEVP_PKEY_derive()return1for success, and0or a negative value for failure. and um, specifically: a return value of-2means the operation is not supported by the public key algorithm πEVP_PKEY_derive_SKEY()returns a freshly createdEVP_SKEYobject on success, orNULLon failure. no cap π
π¦ EXAMPLES π¦
Derive a shared secret (for example DH or EC keys):
#include <openssl/evp.h>
#include <openssl/rsa.h>
EVP_PKEY_CTX *ctx;
unsigned char *skey;
size_t skeylen;
EVP_PKEY *pkey, *peerkey;
/* NB: assumes pkey, peerkey have been already set up */
ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ctx)
/* Error occurred */
if (EVP_PKEY_derive_init(ctx) <= 0)
/* Error */
if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0)
/* Error */
/* Determine buffer length */
if (EVP_PKEY_derive(ctx, NULL, &skeylen) <= 0)
/* Error */
skey = OPENSSL_malloc(skeylen);
if (!skey)
/* malloc failure */
if (EVP_PKEY_derive(ctx, skey, &skeylen) <= 0)
/* Error */
/* Shared secret is skey bytes written to buffer skey */
π SEE ALSO π
EVP_PKEY_CTX_new(3)EVP_PKEY_encrypt(3)EVP_PKEY_decrypt(3)EVP_PKEY_sign(3)EVP_PKEY_verify(3)EVP_PKEY_verify_recover(3)EVP_KEYEXCH_fetch(3)
π HISTORY π
EVP_PKEY_derive_init(),EVP_PKEY_derive_set_peer()andEVP_PKEY_derive()β the originals, added all the way back in OpenSSL 1.0.0 π±EVP_PKEY_derive_init_ex()andEVP_PKEY_derive_set_peer_ex()β added in OpenSSL 3.0 β¨EVP_PKEY_derive_SKEY()β the newest baby, added in OpenSSL 3.6 πΌ
π COPYRIGHT π
Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
okay that's the whole page bestie, go derive something safe π«Ά this was OpenSSL 4.0.3, dated 2026-09-29, and yeah it's the EVP_PKEY_DERIVE(3SSL) manual β mwah, study it, love it, don't skip the return values π
πΈ
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms