EVP_PKEY_NEW(3) | Library Functions Manual | EVP_PKEY_NEW(3)

# NAME

`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`, `EVP_PKEY_get_raw_public_key` — 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

The EVP_PKEY structure is used by various OpenSSL functions which require a general private or public key without reference to any particular algorithm.

The `EVP_PKEY_new`() function allocates an empty EVP_PKEY structure. The reference count is set to 1. To add a private or public key to it, use the functions described in EVP_PKEY_set1_RSA(3).

`EVP_PKEY_up_ref`() increments the reference count of pkey by 1.

`EVP_PKEY_free`() decrements the reference count of pkey by 1, and if the reference count reaches zero, frees it up. If pkey is a `NULL` pointer, no action occurs.

`EVP_PKEY_new_raw_private_key`() allocates a new EVP_PKEY. The NID of a public key algorithm that supports raw private keys, i.e. `EVP_PKEY_HMAC`, `EVP_PKEY_X25519`, or `EVP_PKEY_ED25519`, is provided in the type argument and rawlen bytes of raw private key data of that type in rawpriv. The public key data is automatically derived from the given private key data, if appropriate for the algorithm type. The ENGINE *engine argument is always ignored and passing `NULL` is recommended.

`EVP_PKEY_new_raw_public_key`() works in the same way as `EVP_PKEY_new_raw_private_key`() except that rawpub points to the raw public key data. The EVP_PKEY structure is initialised without any private key information. Algorithm types that support raw public keys are `EVP_PKEY_X25519` and `EVP_PKEY_ED25519`.

`EVP_PKEY_new_mac_key`() is a deprecated function that achieves the same effect as `EVP_PKEY_new_raw_private_key`() in a more complicated way and only works with a type of `EVP_PKEY_HMAC`.

`EVP_PKEY_get_raw_private_key`() writes up to *rawlen bytes of raw private key data to the buffer starting at rawpriv and 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 the rawpriv argument is `NULL`, 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 are `EVP_PKEY_HMAC`, `EVP_PKEY_X25519`, and `EVP_PKEY_ED25519`.

`EVP_PKEY_get_raw_public_key`() is similar to `EVP_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 are `EVP_PKEY_X25519` and `EVP_PKEY_ED25519`.

# RETURN VALUES

`EVP_PKEY_new`(), `EVP_PKEY_new_raw_private_key`(), `EVP_PKEY_new_raw_public_key`(), and `EVP_PKEY_new_mac_key`() return either the newly allocated EVP_PKEY structure or `NULL` if an error occurred.

`EVP_PKEY_up_ref`(), `EVP_PKEY_get_raw_private_key`(), and `EVP_PKEY_get_raw_public_key`() return 1 for success or 0 for 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`() and `EVP_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`(), and `EVP_PKEY_get_raw_public_key`() first appeared in OpenSSL 1.1.1 and have been available since OpenBSD 7.3.

June 8, 2025 | Debian