/* SPDX-License-Identifier: GPL-2.0 */1/*2* Support for AES-CMAC, AES-XCBC-MAC, and AES-CBC-MAC3*4* Copyright 2026 Google LLC5*/6#ifndef _CRYPTO_AES_CBC_MACS_H7#define _CRYPTO_AES_CBC_MACS_H89#include <crypto/aes.h>1011/**12* struct aes_cmac_key - Prepared key for AES-CMAC or AES-XCBC-MAC13* @aes: The AES key for cipher block chaining14* @k_final: Finalization subkeys for the final block.15* k_final[0] (CMAC K1, XCBC-MAC K2) is used if it's a full block.16* k_final[1] (CMAC K2, XCBC-MAC K3) is used if it's a partial block.17*/18struct aes_cmac_key {19struct aes_enckey aes;20union {21u8 b[AES_BLOCK_SIZE];22__be64 w[2];23} k_final[2];24};2526/**27* struct aes_cmac_ctx - Context for computing an AES-CMAC or AES-XCBC-MAC value28* @key: Pointer to the key struct. A pointer is used rather than a copy of the29* struct, since the key struct size may be large. It is assumed that the30* key lives at least as long as the context.31* @partial_len: Number of bytes that have been XOR'ed into @h since the last32* AES encryption. This is 0 if no data has been processed yet,33* or between 1 and AES_BLOCK_SIZE inclusive otherwise.34* @h: The current chaining value35*/36struct aes_cmac_ctx {37const struct aes_cmac_key *key;38size_t partial_len;39u8 h[AES_BLOCK_SIZE];40};4142/**43* aes_cmac_preparekey() - Prepare a key for AES-CMAC44* @key: (output) The key struct to initialize45* @in_key: The raw AES key46* @key_len: Length of the raw key in bytes. The supported values are47* AES_KEYSIZE_128, AES_KEYSIZE_192, and AES_KEYSIZE_256.48*49* Context: Any context.50* Return: 0 on success or -EINVAL if the given key length is invalid. No other51* errors are possible, so callers that always pass a valid key length52* don't need to check for errors.53*/54int aes_cmac_preparekey(struct aes_cmac_key *key, const u8 *in_key,55size_t key_len);5657/**58* aes_xcbcmac_preparekey() - Prepare a key for AES-XCBC-MAC59* @key: (output) The key struct to initialize60* @in_key: The raw key. As per the AES-XCBC-MAC specification (RFC 3566), this61* is 128 bits, matching the internal use of AES-128.62*63* AES-XCBC-MAC and AES-CMAC are the same except for the key preparation. After64* that step, AES-XCBC-MAC is supported via the aes_cmac_* functions.65*66* New users should use AES-CMAC instead of AES-XCBC-MAC.67*68* Context: Any context.69*/70void aes_xcbcmac_preparekey(struct aes_cmac_key *key,71const u8 in_key[at_least AES_KEYSIZE_128]);7273/**74* aes_cmac_init() - Start computing an AES-CMAC or AES-XCBC-MAC value75* @ctx: (output) The context to initialize76* @key: The key to use. Note that a pointer to the key is saved in the77* context, so the key must live at least as long as the context.78*79* This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on80* whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.81*/82static inline void aes_cmac_init(struct aes_cmac_ctx *ctx,83const struct aes_cmac_key *key)84{85*ctx = (struct aes_cmac_ctx){ .key = key };86}8788/**89* aes_cmac_update() - Update an AES-CMAC or AES-XCBC-MAC context with more data90* @ctx: The context to update; must have been initialized91* @data: The message data92* @data_len: The data length in bytes. Doesn't need to be block-aligned.93*94* This can be called any number of times.95*96* Context: Any context.97*/98void aes_cmac_update(struct aes_cmac_ctx *ctx, const u8 *data, size_t data_len);99100/**101* aes_cmac_final() - Finish computing an AES-CMAC or AES-XCBC-MAC value102* @ctx: The context to finalize; must have been initialized103* @out: (output) The resulting MAC104*105* After finishing, this zeroizes @ctx. So the caller does not need to do it.106*107* Context: Any context.108*/109void aes_cmac_final(struct aes_cmac_ctx *ctx, u8 out[at_least AES_BLOCK_SIZE]);110111/**112* aes_cmac() - Compute AES-CMAC or AES-XCBC-MAC in one shot113* @key: The key to use114* @data: The message data115* @data_len: The data length in bytes116* @out: (output) The resulting AES-CMAC or AES-XCBC-MAC value117*118* This supports both AES-CMAC and AES-XCBC-MAC. Which one is done depends on119* whether aes_cmac_preparekey() or aes_xcbcmac_preparekey() was called.120*121* Context: Any context.122*/123static inline void aes_cmac(const struct aes_cmac_key *key, const u8 *data,124size_t data_len, u8 out[at_least AES_BLOCK_SIZE])125{126struct aes_cmac_ctx ctx;127128aes_cmac_init(&ctx, key);129aes_cmac_update(&ctx, data, data_len);130aes_cmac_final(&ctx, out);131}132133/*134* AES-CBC-MAC support. This is provided only for use by the implementation of135* AES-CCM. It should have no other users. Warning: unlike AES-CMAC and136* AES-XCBC-MAC, AES-CBC-MAC isn't a secure MAC for variable-length messages.137*/138struct aes_cbcmac_ctx {139const struct aes_enckey *key;140size_t partial_len;141u8 h[AES_BLOCK_SIZE];142};143static inline void aes_cbcmac_init(struct aes_cbcmac_ctx *ctx,144const struct aes_enckey *key)145{146*ctx = (struct aes_cbcmac_ctx){ .key = key };147}148void aes_cbcmac_update(struct aes_cbcmac_ctx *ctx, const u8 *data,149size_t data_len);150void aes_cbcmac_final(struct aes_cbcmac_ctx *ctx,151u8 out[at_least AES_BLOCK_SIZE]);152153#endif /* _CRYPTO_AES_CBC_MACS_H */154155156