NAME
EVP_PKEY_new_CMAC_key
—
CMAC in the EVP framework
SYNOPSIS
#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.