cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aes_cmac.c (2226B)


      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/crypto.h>
     11#include <linux/export.h>
     12#include <linux/err.h>
     13#include <crypto/aes.h>
     14
     15#include <net/mac80211.h>
     16#include "key.h"
     17#include "aes_cmac.h"
     18
     19#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
     20#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
     21#define AAD_LEN 20
     22
     23static const u8 zero[CMAC_TLEN_256];
     24
     25void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
     26			const u8 *data, size_t data_len, u8 *mic)
     27{
     28	SHASH_DESC_ON_STACK(desc, tfm);
     29	u8 out[AES_BLOCK_SIZE];
     30	const __le16 *fc;
     31
     32	desc->tfm = tfm;
     33
     34	crypto_shash_init(desc);
     35	crypto_shash_update(desc, aad, AAD_LEN);
     36	fc = (const __le16 *)aad;
     37	if (ieee80211_is_beacon(*fc)) {
     38		/* mask Timestamp field to zero */
     39		crypto_shash_update(desc, zero, 8);
     40		crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN);
     41	} else {
     42		crypto_shash_update(desc, data, data_len - CMAC_TLEN);
     43	}
     44	crypto_shash_finup(desc, zero, CMAC_TLEN, out);
     45
     46	memcpy(mic, out, CMAC_TLEN);
     47}
     48
     49void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
     50			    const u8 *data, size_t data_len, u8 *mic)
     51{
     52	SHASH_DESC_ON_STACK(desc, tfm);
     53	const __le16 *fc;
     54
     55	desc->tfm = tfm;
     56
     57	crypto_shash_init(desc);
     58	crypto_shash_update(desc, aad, AAD_LEN);
     59	fc = (const __le16 *)aad;
     60	if (ieee80211_is_beacon(*fc)) {
     61		/* mask Timestamp field to zero */
     62		crypto_shash_update(desc, zero, 8);
     63		crypto_shash_update(desc, data + 8,
     64				    data_len - 8 - CMAC_TLEN_256);
     65	} else {
     66		crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
     67	}
     68	crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
     69}
     70
     71struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
     72						  size_t key_len)
     73{
     74	struct crypto_shash *tfm;
     75
     76	tfm = crypto_alloc_shash("cmac(aes)", 0, 0);
     77	if (!IS_ERR(tfm)) {
     78		int err = crypto_shash_setkey(tfm, key, key_len);
     79
     80		if (err) {
     81			crypto_free_shash(tfm);
     82			return ERR_PTR(err);
     83		}
     84	}
     85
     86	return tfm;
     87}
     88
     89void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm)
     90{
     91	crypto_free_shash(tfm);
     92}