EVP_PKEY_NEW_CMAC_KEY(3)
okay so bestie, welcome to the EVP_PKEY_NEW_CMAC_KEY(3) page from the Library Functions Manual β weβre talking CMAC in the EVP framework, and itβs giving main character crypto energy π
β¨
π NAME π
EVP_PKEY_new_CMAC_key β CMAC in the EVP framework
πΈ SYNOPSIS πΈ
library βlibcryptoβ and #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 π¦
So 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. slay.
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. no cap, that part matters π
The engine argument is ignored; passing NULL is recommended. fr fr, just pass NULL.
π RETURN VALUES π
EVP_PKEY_new_CMAC_key() returns the newly allocated EVP_PKEY structure or NULL if an error occurred. thatβs the vibe check β
β¨ EXAMPLES β¨
The following code digests a message with AES-CMAC using the key length of 128 bits specified in RFC 4493. obsessed, honestly:
/* 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_PKEYwas originally intended to stand for βprivate keyβ and theEVP_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. iykyk π«Ά - 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_PKEYobject. Consequently, theEVP_MD *typeargument ofEVP_DigestSignInit(3)has to be set toNULL. periodt. - 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 thepkeyobject tomd_ctxbut merely increments the reference count. Consequently, the caller is responsible for freeing theEVP_PKEYobject when it is no longer needed. not me forgetting to free itβ¦ donβt be that girl π
π 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. iconic behavior, honestly π
π thatβs the whole page, bestie β sourced from Debian, dated June 8, 2025, for manual EVP_PKEY_NEW_CMAC_KEY(3). mwah π
π
π¦ 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) 2024 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms