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: http://www.openssl.org/docs/crypto/EVP_PKEY_derive.html.
Note that shared secrets derived in this way may not be evenly distributed within the key space. For this reason a shared secret is typically passed through some further function such as a message digest such as SHA2 (possibly combining the shared secret with other well defined data first). Using a shared secret directly as an encryption key could lead to biases in your encryption implementation which in turn is likely to lead to security weaknesses. Refer to section 2.1.2 of RFC 2631 for an example of this in practice.