---
name: "libressl-EVP_PKEY_new_CMAC_key"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-EVP_PKEY_new_CMAC_key"
---

# libressl-EVP\_PKEY\_new\_CMAC\_key(3)

CMAC in the EVP framework

## NAME

**EVP\_PKEY\_new\_CMAC\_key** – CMAC in the EVP framework

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#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.
