EVP Key Agreement
Key derivation is the process of deriving a shared secret between two peers. So, for example, if Alice and Bob wish to communicate then Alice can calculate the shared secret using her private key and Bob's public key using an appropriate key derivation function such as Diffie-Hellman (DH) or Elliptic Curve Diffie-Hellman (ECDH). Similarly Bob can calculate the same shared secret using his own private key, and Alice's public key. This shared secret can then be used as the basis for a key for some symmetric encryption algorithm.
The following code sample is from the OpenSSL manual and shows how a private/public key pair (stored in the variable pkey), and a public key of some peer (stored in the variable peerkey) can be combined to derive the shared secret (stored in the variable skey, with a length stored in skeylen). Obviously equivalent code would be executed on the peer side to come up with the same shared secret.
#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); 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 */
You can only use EVP_PKEY types that support key derivation (currently only DH and ECDH). Clearly in the code sample above the shared secret needs to be "freed" with OPENSSL_free once it is no longer required.
The OpenSSL documentation for the derivation functions is available here: https://www.openssl.org/docs/crypto/EVP_PKEY_derive.html