1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * AES-128-CMAC with TLen 16 for IEEE 802.11w BIP 4 * Copyright 2008, Jouni Malinen <j@w1.fi> 5 * Copyright (C) 2020 Intel Corporation 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/types.h> 10 #include <linux/export.h> 11 #include <linux/err.h> 12 #include <crypto/aes-cbc-macs.h> 13 14 #include <net/mac80211.h> 15 #include "key.h" 16 #include "aes_cmac.h" 17 18 #define AAD_LEN 20 19 20 static const u8 zero[IEEE80211_CMAC_256_MIC_LEN]; 21 22 void ieee80211_aes_cmac(const struct aes_cmac_key *key, const u8 *aad, 23 const u8 *data, size_t data_len, u8 *mic, 24 unsigned int mic_len) 25 { 26 struct aes_cmac_ctx ctx; 27 u8 out[AES_BLOCK_SIZE]; 28 const __le16 *fc; 29 30 aes_cmac_init(&ctx, key); 31 aes_cmac_update(&ctx, aad, AAD_LEN); 32 fc = (const __le16 *)aad; 33 if (ieee80211_is_beacon(*fc)) { 34 /* mask Timestamp field to zero */ 35 aes_cmac_update(&ctx, zero, 8); 36 aes_cmac_update(&ctx, data + 8, data_len - 8 - mic_len); 37 } else { 38 aes_cmac_update(&ctx, data, data_len - mic_len); 39 } 40 aes_cmac_update(&ctx, zero, mic_len); 41 aes_cmac_final(&ctx, out); 42 memcpy(mic, out, mic_len); 43 } 44