EVP_PKEY_NEW_CMAC_KEY(3) | Library Functions Manual | EVP_PKEY_NEW_CMAC_KEY(3)

# NAME

`EVP_PKEY_new_CMAC_key` — CMAC in the EVP framework

# SYNOPSIS

library “libcrypto”
`#include <openssl/evp.h>`

EVP_PKEY *
`EVP_PKEY_new_CMAC_key`(ENGINE *engine, const unsigned char *key, size_t key_len, const EVP_CIPHER *cipher);

# DESCRIPTION

`EVP_PKEY_new_CMAC_key`() allocates a new EVP_PKEY object, sets its type to `EVP_PKEY_CMAC`, and configures it as a wrapper around the low-level functions documented in CMAC_Init(3) using the block cipher with the symmetric key that is key_len bytes long.

Functions to obtain suitable EVP_CIPHER objects are listed in the CIPHER LISTING section of the EVP_EncryptInit(3) manual page. Always use an object that implements the CBC mode of operation. As in CMAC_Init(3), only ciphers with a block size of either 64 or 128 bits are supported by this implementation.

The engine argument is ignored; passing `NULL` is recommended.

# RETURN VALUES

`EVP_PKEY_new_CMAC_key`() returns the newly allocated EVP_PKEY structure or `NULL` if an error occurred.

# EXAMPLES

The following code digests a message with AES-CMAC using the key length of 128 bits specified in RFC 4493.

    /* Bogus key: would normally be set from another source. */
    const unsigned char key[] = "symmetric secret";
    const size_t key_len = strlen(key);  /* 16 = 128/8 */

    const char *msg = "Hello World!";
    const size_t msg_len = strlen(msg);

    unsigned char out_mac[16];
    size_t out_len = sizeof(out_mac);
    size_t i;

    EVP_PKEY *pkey;
    EVP_MD_CTX *md_ctx;

    pkey = EVP_PKEY_new_CMAC_key(NULL, key, key_len, EVP_aes_128_cbc());
    if (pkey == NULL)
    	err(1, "EVP_PKEY_new_CMAC_key");
    md_ctx = EVP_MD_CTX_new();
    if (md_ctx == NULL)
    	err(1, "EVP_MD_CTX_new");

    if (EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey) == 0)
    	err(1, "EVP_DigestSignInit");
    if (EVP_DigestSign(md_ctx, out_mac, &out_len, msg, msg_len) == 0)
    	err(1, "EVP_DigestSign");
    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");

Consider the following details:

- 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.
- In contrast to digital signing which requires both a digest algorithm and a private key, the CMAC algorithm only requires a block cipher and a shared key, both of which are stored in the somewhat abused EVP_PKEY object. Consequently, the EVP_MD *type argument of EVP_DigestSignInit(3) has to be set to `NULL`.
- The size of the resulting message digest equals the block size of the used cipher.
- The function EVP_DigestSignInit(3) does not transfer ownership of the pkey object to md_ctx but merely increments the reference count. Consequently, the caller is responsible for freeing the EVP_PKEY object when it is no longer needed.

# SEE ALSO

CMAC_Init(3), evp(3), EVP_DigestSignInit(3), EVP_EncryptInit(3), EVP_PKEY_new(3)

# STANDARDS

RFC 4493: The AES-CMAC Algorithm

# HISTORY

`EVP_PKEY_new_CMAC_key`() first appeared in OpenSSL 1.1.1 and has been available since OpenBSD 6.9.

June 8, 2025 | Debian