EVP_PKEY_NEW(3)
πΈ NAME πΈ
hey bestie, welcome to EVP_PKEY_NEW(3) from the Library Functions Manual β we're talking public and private key allocation plus raw key handling, and it's lowkey iconic. The whole squad is: EVP_PKEY_new, EVP_PKEY_up_ref, EVP_PKEY_free, EVP_PKEY_new_raw_private_key, EVP_PKEY_new_raw_public_key, EVP_PKEY_new_mac_key, EVP_PKEY_get_raw_private_key, and EVP_PKEY_get_raw_public_key β literally public and private key allocation and raw key handling functions.
β¨ SYNOPSIS β¨
library βlibcryptoβ #include <openssl/evp.h>
EVP_PKEY *
EVP_PKEY_new(void);
int
EVP_PKEY_up_ref(EVP_PKEY *pkey);
void
EVP_PKEY_free(EVP_PKEY *pkey);
EVP_PKEY *
EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
const unsigned char *rawpriv, size_t rawlen);
EVP_PKEY *
EVP_PKEY_new_raw_public_key(int type, ENGINE *engine,
const unsigned char *rawpub, size_t rawlen);
EVP_PKEY *
EVP_PKEY_new_mac_key(int type, ENGINE *engine,
const unsigned char *rawpriv, int rawlen);
int
EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey,
unsigned char *rawpriv, size_t *rawlen);
int
EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *rawpub,
size_t *rawlen);
π¦ DESCRIPTION π¦
okay so the EVP_PKEY structure is used by various OpenSSL functions that need a general private or public key without referencing any particular algorithm. it's giving "one key type to rule them all" energy.
EVP_PKEY_new()allocates an emptyEVP_PKEYstructure. The reference count is set to1. To add a private or public key to it, use the functions described inEVP_PKEY_set1_RSA(3).EVP_PKEY_up_ref()increments the reference count ofpkeyby1.EVP_PKEY_free()decrements the reference count ofpkeyby1, and if the reference count reaches zero, frees it up. Ifpkeyis aNULLpointer, no action occurs.EVP_PKEY_new_raw_private_key()allocates a newEVP_PKEY. The NID of a public key algorithm that supports raw private keys β i.e.EVP_PKEY_HMAC,EVP_PKEY_X25519, orEVP_PKEY_ED25519β is provided in thetypeargument, andrawlenbytes of raw private key data of that type go inrawpriv. The public key data is automatically derived from the given private key data, if appropriate for the algorithm type. TheENGINE *engineargument is always ignored and passingNULLis recommended.EVP_PKEY_new_raw_public_key()works in the same way asEVP_PKEY_new_raw_private_key()except thatrawpubpoints to the raw public key data. TheEVP_PKEYstructure is initialised without any private key information. Algorithm types that support raw public keys areEVP_PKEY_X25519andEVP_PKEY_ED25519.EVP_PKEY_new_mac_key()is a deprecated function that achieves the same effect asEVP_PKEY_new_raw_private_key()in a more complicated way and only works with a type ofEVP_PKEY_HMAC.
β οΈ bestie, did you catch that?EVP_PKEY_new_mac_key()is deprecated. it's the complicated older sibling, and it only works withEVP_PKEY_HMAC.
EVP_PKEY_get_raw_private_key()writes up to*rawlenbytes of raw private key data to the buffer starting atrawprivand stores the number of bytes written in*rawlen. The calling application is responsible for ensuring that the buffer is large enough to receive the private key data. If therawprivargument isNULL, the number of bytes required to hold the key is stored in*rawlen. This function only works for algorithms that support raw private keys. Currently these areEVP_PKEY_HMAC,EVP_PKEY_X25519, andEVP_PKEY_ED25519.EVP_PKEY_get_raw_public_key()is similar toEVP_PKEY_get_raw_private_key()except that it writes raw public key data. This function only works for algorithms that support raw public keys. Currently these areEVP_PKEY_X25519andEVP_PKEY_ED25519.
π RETURN VALUES π
EVP_PKEY_new(),EVP_PKEY_new_raw_private_key(),EVP_PKEY_new_raw_public_key(), andEVP_PKEY_new_mac_key()return either the newly allocatedEVP_PKEYstructure orNULLif an error occurred.EVP_PKEY_up_ref(),EVP_PKEY_get_raw_private_key(), andEVP_PKEY_get_raw_public_key()return1for success or0for failure.
π EXAMPLES π
The following code digests a message with HMAC-SHA256:
/* Bogus key: would normally be set from another source */
const unsigned char *key = "key";
const size_t key_len = strlen(key);
const char *msg = "The quick brown fox jumps over the lazy dog";
const size_t msg_len = strlen(msg);
unsigned char *out_mac;
size_t out_len, i;
EVP_PKEY *pkey;
EVP_MD_CTX *md_ctx;
pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
key, key_len);
if (pkey == NULL)
err(1, "EVP_PKEY_new_raw_private_key");
md_ctx = EVP_MD_CTX_new();
if (md_ctx == NULL)
err(1, "EVP_MD_CTX_new");
if (EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) == 0)
err(1, "EVP_DigestSignInit");
if (EVP_DigestSign(md_ctx, NULL, &out_len, msg, msg_len) == 0)
err(1, "EVP_DigestSign(NULL)");
if ((out_mac = calloc(1, out_len)) == NULL)
err(1, "calloc");
if (EVP_DigestSign(md_ctx, out_mac, &out_len, msg, msg_len) == 0)
err(1, "EVP_DigestSign(MAC)");
EVP_MD_CTX_free(md_ctx);
EVP_PKEY_free(pkey);
printf(" MAC = ");
for (i = 0; i < out_len; i++)
printf("%02x", out_mac[i]);
printf("\n");
free(out_mac);
Even though the type name EVP_PKEY was originally intended to stand for βprivate keyβ and the EVP_DigestSignInit(3) API was designed for digital signatures in the context of public key cryptography, both are also used here because a MAC also requires a key, even though that is a symmetric key.
The same code can be used for signing with Ed25519 by making the key ED25519_PRIVATE_KEY_LENGTH = 32 bytes long, replacing EVP_PKEY_HMAC with EVP_PKEY_ED25519, and replacing the call to EVP_sha256(3) with NULL.
π SEE ALSO π
CMAC_Init(3)d2i_PrivateKey(3)evp(3)EVP_PKCS82PKEY(3)EVP_PKEY_cmp(3)EVP_PKEY_CTX_new(3)EVP_PKEY_get_default_digest_nid(3)EVP_PKEY_new_CMAC_key(3)EVP_PKEY_print_private(3)EVP_PKEY_set1_RSA(3)EVP_PKEY_size(3)X509_get_pubkey_parameters(3)
β HISTORY β
EVP_PKEY_new()andEVP_PKEY_free()first appeared in SSLeay 0.6.0 and have been available since OpenBSD 2.4.EVP_PKEY_new_mac_key()first appeared in OpenSSL 1.0.0 and has been available since OpenBSD 4.9.EVP_PKEY_up_ref()first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 6.3.EVP_PKEY_new_raw_private_key(),EVP_PKEY_new_raw_public_key(),EVP_PKEY_get_raw_private_key(), andEVP_PKEY_get_raw_public_key()first appeared in OpenSSL 1.1.1 and have been available since OpenBSD 7.3.
kisses from Debian, June 8, 2025 β this was EVP_PKEY_NEW(3), and she ate. πβ¨
π¦ 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) 2022, 2024 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2002, 2018, 2020 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