// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2002-2004, Instant802 Networks, Inc.
 * Copyright 2008, Jouni Malinen <j@w1.fi>
 * Copyright (C) 2016-2017 Intel Deutschland GmbH
 * Copyright (C) 2020-2023 Intel Corporation
 */

#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>
#include <linux/ieee80211.h>
#include <linux/gfp.h>
#include <linux/unaligned.h>
#include <net/mac80211.h>
#include <crypto/aes.h>
#include <crypto/utils.h>

#include "ieee80211_i.h"
#include "michael.h"
#include "tkip.h"
#include "aes_ccm.h"
#include "aes_cmac.h"
#include "aes_gmac.h"
#include "aes_gcm.h"
#include "wpa.h"

ieee80211_tx_result
ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
{
	u8 *data, *key, *mic;
	size_t data_len;
	unsigned int hdrlen;
	struct ieee80211_hdr *hdr;
	struct sk_buff *skb = tx->skb;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int tail;

	hdr = (struct ieee80211_hdr *)skb->data;
	if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
	    skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
		return TX_CONTINUE;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	if (skb->len < hdrlen)
		return TX_DROP;

	data = skb->data + hdrlen;
	data_len = skb->len - hdrlen;

	if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE)) {
		/* Need to use software crypto for the test */
		info->control.hw_key = NULL;
	}

	if (info->control.hw_key &&
	    (info->flags & IEEE80211_TX_CTL_DONTFRAG ||
	     ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG)) &&
	    !(tx->key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC |
				     IEEE80211_KEY_FLAG_PUT_MIC_SPACE))) {
		/* hwaccel - with no need for SW-generated MMIC or MIC space */
		return TX_CONTINUE;
	}

	tail = MICHAEL_MIC_LEN;
	if (!info->control.hw_key)
		tail += IEEE80211_TKIP_ICV_LEN;

	if (WARN(skb_tailroom(skb) < tail ||
		 skb_headroom(skb) < IEEE80211_TKIP_IV_LEN,
		 "mmic: not enough head/tail (%d/%d,%d/%d)\n",
		 skb_headroom(skb), IEEE80211_TKIP_IV_LEN,
		 skb_tailroom(skb), tail))
		return TX_DROP;

	mic = skb_put(skb, MICHAEL_MIC_LEN);

	if (tx->key->conf.flags & IEEE80211_KEY_FLAG_PUT_MIC_SPACE) {
		/* Zeroed MIC can help with debug */
		memset(mic, 0, MICHAEL_MIC_LEN);
		return TX_CONTINUE;
	}

	key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
	michael_mic(key, hdr, data, data_len, mic);
	if (unlikely(info->flags & IEEE80211_TX_INTFL_TKIP_MIC_FAILURE))
		mic[0]++;

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
{
	u8 *data, *key = NULL;
	size_t data_len;
	unsigned int hdrlen;
	u8 mic[MICHAEL_MIC_LEN];
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;

	/*
	 * it makes no sense to check for MIC errors on anything other
	 * than data frames.
	 */
	if (!ieee80211_is_data_present(hdr->frame_control))
		return RX_CONTINUE;

	/*
	 * No way to verify the MIC if the hardware stripped it or
	 * the IV with the key index. In this case we have solely rely
	 * on the driver to set RX_FLAG_MMIC_ERROR in the event of a
	 * MIC failure report.
	 */
	if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
		if (status->flag & RX_FLAG_MMIC_ERROR)
			goto mic_fail_no_key;

		if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key &&
		    rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)
			goto update_iv;

		return RX_CONTINUE;
	}

	/*
	 * Some hardware seems to generate Michael MIC failure reports; even
	 * though, the frame was not encrypted with TKIP and therefore has no
	 * MIC. Ignore the flag them to avoid triggering countermeasures.
	 */
	if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
	    !(status->flag & RX_FLAG_DECRYPTED))
		return RX_CONTINUE;

	if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) {
		/*
		 * APs with pairwise keys should never receive Michael MIC
		 * errors for non-zero keyidx because these are reserved for
		 * group keys and only the AP is sending real multicast
		 * frames in the BSS.
		 */
		return RX_DROP_U_AP_RX_GROUPCAST;
	}

	if (status->flag & RX_FLAG_MMIC_ERROR)
		goto mic_fail;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	if (skb->len < hdrlen + MICHAEL_MIC_LEN)
		return RX_DROP_U_SHORT_MMIC;

	if (skb_linearize(rx->skb))
		return RX_DROP_U_OOM;
	hdr = (void *)skb->data;

	data = skb->data + hdrlen;
	data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
	key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
	michael_mic(key, hdr, data, data_len, mic);
	if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN))
		goto mic_fail;

	/* remove Michael MIC from payload */
	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);

update_iv:
	/* update IV in key information to be able to detect replays */
	rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32;
	rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16;

	return RX_CONTINUE;

mic_fail:
	rx->key->u.tkip.mic_failures++;

mic_fail_no_key:
	/*
	 * In some cases the key can be unset - e.g. a multicast packet, in
	 * a driver that supports HW encryption. Send up the key idx only if
	 * the key is set.
	 */
	cfg80211_michael_mic_failure(rx->sdata->dev, hdr->addr2,
				     is_multicast_ether_addr(hdr->addr1) ?
				     NL80211_KEYTYPE_GROUP :
				     NL80211_KEYTYPE_PAIRWISE,
				     rx->key ? rx->key->conf.keyidx : -1,
				     NULL, GFP_ATOMIC);
	return RX_DROP_U_MMIC_FAIL;
}

static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	unsigned int hdrlen;
	int len, tail;
	u64 pn;
	u8 *pos;

	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
		/* hwaccel - with no need for software-generated IV */
		return 0;
	}

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	len = skb->len - hdrlen;

	if (info->control.hw_key)
		tail = 0;
	else
		tail = IEEE80211_TKIP_ICV_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
		return -1;

	pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
	memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
	pos += hdrlen;

	/* the HW only needs room for the IV, but not the actual IV */
	if (info->control.hw_key &&
	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
		return 0;

	/* Increase IV for the frame */
	pn = atomic64_inc_return(&key->conf.tx_pn);
	pos = ieee80211_tkip_add_iv(pos, &key->conf, pn);

	/* hwaccel - with software IV */
	if (info->control.hw_key)
		return 0;

	/* Add room for ICV */
	skb_put(skb, IEEE80211_TKIP_ICV_LEN);

	return ieee80211_tkip_encrypt_data(&tx->local->wep_tx_ctx,
					   key, skb, pos, len);
}


ieee80211_tx_result
ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;

	ieee80211_tx_set_protected(tx);

	skb_queue_walk(&tx->skbs, skb) {
		if (tkip_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
	}

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
	int hdrlen, res, hwaccel = 0;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if (!ieee80211_is_data(hdr->frame_control))
		return RX_CONTINUE;

	if (!rx->sta || skb->len - hdrlen < 12)
		return RX_DROP_U_SHORT_TKIP;

	/* it may be possible to optimize this a bit more */
	if (skb_linearize(rx->skb))
		return RX_DROP_U_OOM;
	hdr = (void *)skb->data;

	/*
	 * Let TKIP code verify IV, but skip decryption.
	 * In the case where hardware checks the IV as well,
	 * we don't even get here, see ieee80211_rx_h_decrypt()
	 */
	if (status->flag & RX_FLAG_DECRYPTED)
		hwaccel = 1;

	res = ieee80211_tkip_decrypt_data(&rx->local->wep_rx_ctx,
					  key, skb->data + hdrlen,
					  skb->len - hdrlen, rx->sta->sta.addr,
					  hdr->addr1, hwaccel, rx->security_idx,
					  &rx->tkip.iv32,
					  &rx->tkip.iv16);
	if (res != TKIP_DECRYPT_OK)
		return RX_DROP_U_TKIP_FAIL;

	/* Trim ICV */
	if (!(status->flag & RX_FLAG_ICV_STRIPPED))
		skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);

	/* Remove IV */
	memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
	skb_pull(skb, IEEE80211_TKIP_IV_LEN);

	return RX_CONTINUE;
}

/*
 * Calculate AAD for CCMP/GCMP, returning qos_tid since we
 * need that in CCMP also for b_0.
 */
static u8 ccmp_gcmp_aad(struct sk_buff *skb, u8 *aad, bool spp_amsdu)
{
	struct ieee80211_hdr *hdr = (void *)skb->data;
	__le16 mask_fc;
	int a4_included, mgmt;
	u8 qos_tid;
	u16 len_a = 22;

	/*
	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
	 * Retry, PwrMgt, MoreData, Order (if Qos Data); set Protected
	 */
	mgmt = ieee80211_is_mgmt(hdr->frame_control);
	mask_fc = hdr->frame_control;
	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
				IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
	if (!mgmt)
		mask_fc &= ~cpu_to_le16(0x0070);
	mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);

	a4_included = ieee80211_has_a4(hdr->frame_control);
	if (a4_included)
		len_a += 6;

	if (ieee80211_is_data_qos(hdr->frame_control)) {
		qos_tid = *ieee80211_get_qos_ctl(hdr);

		if (spp_amsdu)
			qos_tid &= IEEE80211_QOS_CTL_TID_MASK |
				   IEEE80211_QOS_CTL_A_MSDU_PRESENT;
		else
			qos_tid &= IEEE80211_QOS_CTL_TID_MASK;

		mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_ORDER);
		len_a += 2;
	} else {
		qos_tid = 0;
	}

	/* AAD (extra authenticate-only data) / masked 802.11 header
	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
	put_unaligned_be16(len_a, &aad[0]);
	put_unaligned(mask_fc, (__le16 *)&aad[2]);
	memcpy(&aad[4], &hdr->addrs, 3 * ETH_ALEN);

	/* Mask Seq#, leave Frag# */
	aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
	aad[23] = 0;

	if (a4_included) {
		memcpy(&aad[24], hdr->addr4, ETH_ALEN);
		aad[30] = qos_tid;
		aad[31] = 0;
	} else {
		memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
		aad[24] = qos_tid;
	}

	return qos_tid;
}

static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
				bool spp_amsdu)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	u8 qos_tid = ccmp_gcmp_aad(skb, aad, spp_amsdu);

	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
	 * mode authentication are not allowed to collide, yet both are derived
	 * from this vector b_0. We only set L := 1 here to indicate that the
	 * data size can be represented in (L+1) bytes. The CCM layer will take
	 * care of storing the data length in the top (L+1) bytes and setting
	 * and clearing the other bits as is required to derive the two IVs.
	 */
	b_0[0] = 0x1;

	/* Nonce: Nonce Flags | A2 | PN
	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
	 */
	b_0[1] = qos_tid | (ieee80211_is_mgmt(hdr->frame_control) << 4);
	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
}

static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id)
{
	hdr[0] = pn[5];
	hdr[1] = pn[4];
	hdr[2] = 0;
	hdr[3] = 0x20 | (key_id << 6);
	hdr[4] = pn[3];
	hdr[5] = pn[2];
	hdr[6] = pn[1];
	hdr[7] = pn[0];
}


static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
{
	pn[0] = hdr[7];
	pn[1] = hdr[6];
	pn[2] = hdr[5];
	pn[3] = hdr[4];
	pn[4] = hdr[1];
	pn[5] = hdr[0];
}


static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb,
			    unsigned int mic_len)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int hdrlen, len, tail;
	u8 *pos;
	u8 pn[6];
	u64 pn64;
	u8 aad[CCM_AAD_LEN];
	u8 b_0[AES_BLOCK_SIZE];

	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
	    !((info->control.hw_key->flags &
	       IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
	      ieee80211_is_mgmt(hdr->frame_control))) {
		/*
		 * hwaccel has no need for preallocated room for CCMP
		 * header or MIC fields
		 */
		return 0;
	}

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	len = skb->len - hdrlen;

	if (info->control.hw_key)
		tail = 0;
	else
		tail = mic_len;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
		return -1;

	pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
	memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);

	/* the HW only needs room for the IV, but not the actual IV */
	if (info->control.hw_key &&
	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
		return 0;

	pos += hdrlen;

	pn64 = atomic64_inc_return(&key->conf.tx_pn);

	pn[5] = pn64;
	pn[4] = pn64 >> 8;
	pn[3] = pn64 >> 16;
	pn[2] = pn64 >> 24;
	pn[1] = pn64 >> 32;
	pn[0] = pn64 >> 40;

	ccmp_pn2hdr(pos, pn, key->conf.keyidx);

	/* hwaccel - with software CCMP header */
	if (info->control.hw_key)
		return 0;

	pos += IEEE80211_CCMP_HDR_LEN;
	ccmp_special_blocks(skb, pn, b_0, aad,
			    key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
	return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
					 skb_put(skb, mic_len));
}


ieee80211_tx_result
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx,
			      unsigned int mic_len)
{
	struct sk_buff *skb;

	ieee80211_tx_set_protected(tx);

	skb_queue_walk(&tx->skbs, skb) {
		if (ccmp_encrypt_skb(tx, skb, mic_len) < 0)
			return TX_DROP;
	}

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
			      unsigned int mic_len)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
	int hdrlen;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	u8 pn[IEEE80211_CCMP_PN_LEN];
	int data_len;
	int queue;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if (!ieee80211_is_data(hdr->frame_control) &&
	    !ieee80211_is_robust_mgmt_frame(skb) &&
	    !ieee80211_require_encrypted_assoc(hdr->frame_control, rx->sta))
		return RX_CONTINUE;

	if (status->flag & RX_FLAG_DECRYPTED) {
		if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
			return RX_DROP_U_SHORT_CCMP;
		if (status->flag & RX_FLAG_MIC_STRIPPED)
			mic_len = 0;
	} else {
		if (skb_linearize(rx->skb))
			return RX_DROP_U_OOM;
	}

	/* reload hdr - skb might have been reallocated */
	hdr = (void *)rx->skb->data;

	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
	if (!rx->sta || data_len < 0)
		return RX_DROP_U_SHORT_CCMP;

	if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
		int res;

		ccmp_hdr2pn(pn, skb->data + hdrlen);

		queue = rx->security_idx;

		res = memcmp(pn, key->u.ccmp.rx_pn[queue],
			     IEEE80211_CCMP_PN_LEN);
		if (res < 0 ||
		    (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
			key->u.ccmp.replays++;
			return RX_DROP_U_REPLAY;
		}

		if (!(status->flag & RX_FLAG_DECRYPTED)) {
			u8 aad[2 * AES_BLOCK_SIZE];
			u8 b_0[AES_BLOCK_SIZE];
			/* hardware didn't decrypt/verify MIC */
			ccmp_special_blocks(skb, pn, b_0, aad,
					    key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);

			if (ieee80211_aes_ccm_decrypt(
				    key->u.ccmp.tfm, b_0, aad,
				    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
				    data_len,
				    skb->data + skb->len - mic_len))
				return RX_DROP_U_MIC_FAIL;
		}

		memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
		if (unlikely(ieee80211_is_frag(hdr)))
			memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
	}

	/* Remove CCMP header and MIC */
	if (pskb_trim(skb, skb->len - mic_len))
		return RX_DROP_U_SHORT_CCMP_MIC;
	memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
	skb_pull(skb, IEEE80211_CCMP_HDR_LEN);

	return RX_CONTINUE;
}

static void gcmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *j_0, u8 *aad,
				bool spp_amsdu)
{
	struct ieee80211_hdr *hdr = (void *)skb->data;

	memcpy(j_0, hdr->addr2, ETH_ALEN);
	memcpy(&j_0[ETH_ALEN], pn, IEEE80211_GCMP_PN_LEN);

	ccmp_gcmp_aad(skb, aad, spp_amsdu);
}

static inline void gcmp_pn2hdr(u8 *hdr, const u8 *pn, int key_id)
{
	hdr[0] = pn[5];
	hdr[1] = pn[4];
	hdr[2] = 0;
	hdr[3] = 0x20 | (key_id << 6);
	hdr[4] = pn[3];
	hdr[5] = pn[2];
	hdr[6] = pn[1];
	hdr[7] = pn[0];
}

static inline void gcmp_hdr2pn(u8 *pn, const u8 *hdr)
{
	pn[0] = hdr[7];
	pn[1] = hdr[6];
	pn[2] = hdr[5];
	pn[3] = hdr[4];
	pn[4] = hdr[1];
	pn[5] = hdr[0];
}

static int gcmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	int hdrlen, len, tail;
	u8 *pos;
	u8 pn[6];
	u64 pn64;
	u8 aad[GCM_AAD_LEN];
	u8 j_0[AES_BLOCK_SIZE];

	if (info->control.hw_key &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
	    !((info->control.hw_key->flags &
	       IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
	      ieee80211_is_mgmt(hdr->frame_control))) {
		/* hwaccel has no need for preallocated room for GCMP
		 * header or MIC fields
		 */
		return 0;
	}

	hdrlen = ieee80211_hdrlen(hdr->frame_control);
	len = skb->len - hdrlen;

	if (info->control.hw_key)
		tail = 0;
	else
		tail = IEEE80211_GCMP_MIC_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < IEEE80211_GCMP_HDR_LEN))
		return -1;

	pos = skb_push(skb, IEEE80211_GCMP_HDR_LEN);
	memmove(pos, pos + IEEE80211_GCMP_HDR_LEN, hdrlen);
	skb_set_network_header(skb, skb_network_offset(skb) +
				    IEEE80211_GCMP_HDR_LEN);

	/* the HW only needs room for the IV, but not the actual IV */
	if (info->control.hw_key &&
	    (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
		return 0;

	pos += hdrlen;

	pn64 = atomic64_inc_return(&key->conf.tx_pn);

	pn[5] = pn64;
	pn[4] = pn64 >> 8;
	pn[3] = pn64 >> 16;
	pn[2] = pn64 >> 24;
	pn[1] = pn64 >> 32;
	pn[0] = pn64 >> 40;

	gcmp_pn2hdr(pos, pn, key->conf.keyidx);

	/* hwaccel - with software GCMP header */
	if (info->control.hw_key)
		return 0;

	pos += IEEE80211_GCMP_HDR_LEN;
	gcmp_special_blocks(skb, pn, j_0, aad,
			    key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);
	return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
					 skb_put(skb, IEEE80211_GCMP_MIC_LEN));
}

ieee80211_tx_result
ieee80211_crypto_gcmp_encrypt(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;

	ieee80211_tx_set_protected(tx);

	skb_queue_walk(&tx->skbs, skb) {
		if (gcmp_encrypt_skb(tx, skb) < 0)
			return TX_DROP;
	}

	return TX_CONTINUE;
}

ieee80211_rx_result
ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
	int hdrlen;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	u8 pn[IEEE80211_GCMP_PN_LEN];
	int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if (!ieee80211_is_data(hdr->frame_control) &&
	    !ieee80211_is_robust_mgmt_frame(skb) &&
	    !ieee80211_require_encrypted_assoc(hdr->frame_control, rx->sta))
		return RX_CONTINUE;

	if (status->flag & RX_FLAG_DECRYPTED) {
		if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
			return RX_DROP_U_SHORT_GCMP;
		if (status->flag & RX_FLAG_MIC_STRIPPED)
			mic_len = 0;
	} else {
		if (skb_linearize(rx->skb))
			return RX_DROP_U_OOM;
	}

	/* reload hdr - skb might have been reallocated */
	hdr = (void *)rx->skb->data;

	data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
	if (!rx->sta || data_len < 0)
		return RX_DROP_U_SHORT_GCMP;

	if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
		int res;

		gcmp_hdr2pn(pn, skb->data + hdrlen);

		queue = rx->security_idx;

		res = memcmp(pn, key->u.gcmp.rx_pn[queue],
			     IEEE80211_GCMP_PN_LEN);
		if (res < 0 ||
		    (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
			key->u.gcmp.replays++;
			return RX_DROP_U_REPLAY;
		}

		if (!(status->flag & RX_FLAG_DECRYPTED)) {
			u8 aad[2 * AES_BLOCK_SIZE];
			u8 j_0[AES_BLOCK_SIZE];
			/* hardware didn't decrypt/verify MIC */
			gcmp_special_blocks(skb, pn, j_0, aad,
					    key->conf.flags & IEEE80211_KEY_FLAG_SPP_AMSDU);

			if (ieee80211_aes_gcm_decrypt(
				    key->u.gcmp.tfm, j_0, aad,
				    skb->data + hdrlen + IEEE80211_GCMP_HDR_LEN,
				    data_len,
				    skb->data + skb->len -
				    IEEE80211_GCMP_MIC_LEN))
				return RX_DROP_U_MIC_FAIL;
		}

		memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN);
		if (unlikely(ieee80211_is_frag(hdr)))
			memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN);
	}

	/* Remove GCMP header and MIC */
	if (pskb_trim(skb, skb->len - mic_len))
		return RX_DROP_U_SHORT_GCMP_MIC;
	memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
	skb_pull(skb, IEEE80211_GCMP_HDR_LEN);

	return RX_CONTINUE;
}

static void bip_aad(struct sk_buff *skb, u8 *aad)
{
	__le16 mask_fc;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;

	/* BIP AAD: FC(masked) || A1 || A2 || A3 */

	/* FC type/subtype */
	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
	mask_fc = hdr->frame_control;
	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM |
				IEEE80211_FCTL_MOREDATA);
	put_unaligned(mask_fc, (__le16 *) &aad[0]);
	/* A1 || A2 || A3 */
	memcpy(aad + 2, &hdr->addrs, 3 * ETH_ALEN);
}


static inline void bip_ipn_set64(u8 *d, u64 pn)
{
	*d++ = pn;
	*d++ = pn >> 8;
	*d++ = pn >> 16;
	*d++ = pn >> 24;
	*d++ = pn >> 32;
	*d = pn >> 40;
}

static inline void bip_ipn_swap(u8 *d, const u8 *s)
{
	*d++ = s[5];
	*d++ = s[4];
	*d++ = s[3];
	*d++ = s[2];
	*d++ = s[1];
	*d = s[0];
}


ieee80211_tx_result
ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx,
				  unsigned int mic_len)
{
	struct sk_buff *skb;
	struct ieee80211_tx_info *info;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_mmie_var *mmie;
	size_t mmie_len;
	u8 aad[20];
	u64 pn64;

	if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
		return TX_DROP;

	skb = skb_peek(&tx->skbs);

	info = IEEE80211_SKB_CB(skb);

	if (info->control.hw_key &&
	    !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
		return TX_CONTINUE;

	mmie_len = sizeof(*mmie) + mic_len;

	if (WARN_ON(skb_tailroom(skb) < mmie_len))
		return TX_DROP;

	mmie = skb_put(skb, mmie_len);
	mmie->element_id = WLAN_EID_MMIE;
	mmie->length = mmie_len - 2;
	mmie->key_id = cpu_to_le16(key->conf.keyidx);

	/* PN = PN + 1 */
	pn64 = atomic64_inc_return(&key->conf.tx_pn);

	bip_ipn_set64(mmie->sequence_number, pn64);

	if (info->control.hw_key)
		return TX_CONTINUE;

	bip_aad(skb, aad);

	if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
			       skb->data + 24, skb->len - 24,
			       mmie->mic, mic_len))
		return TX_DROP;

	return TX_CONTINUE;
}

ieee80211_rx_result
ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx,
				  unsigned int mic_len)
{
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	struct ieee80211_key *key = rx->key;
	struct ieee80211_mmie_var *mmie;
	size_t mmie_len;
	u8 aad[20], mic[IEEE80211_CMAC_256_MIC_LEN], ipn[6];
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;

	if (!ieee80211_is_mgmt(hdr->frame_control))
		return RX_CONTINUE;

	mmie_len = sizeof(*mmie) + mic_len;

	/* management frames are already linear */

	if (skb->len < 24 + mmie_len)
		return mic_len == IEEE80211_CMAC_128_MIC_LEN ?
			RX_DROP_U_SHORT_CMAC : RX_DROP_U_SHORT_CMAC256;

	mmie = (struct ieee80211_mmie_var *)(skb->data + skb->len - mmie_len);
	if (mmie->element_id != WLAN_EID_MMIE ||
	    mmie->length != mmie_len - 2)
		return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */

	bip_ipn_swap(ipn, mmie->sequence_number);

	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
		key->u.aes_cmac.replays++;
		return RX_DROP_U_REPLAY;
	}

	if (!(status->flag & RX_FLAG_DECRYPTED)) {
		/* hardware didn't decrypt/verify MIC */
		bip_aad(skb, aad);
		if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
				       skb->data + 24, skb->len - 24,
				       mic, mic_len))
			return RX_DROP_U_DECRYPT_FAIL;
		if (crypto_memneq(mic, mmie->mic, mic_len)) {
			key->u.aes_cmac.icverrors++;
			return RX_DROP_U_MIC_FAIL;
		}
	}

	memcpy(key->u.aes_cmac.rx_pn, ipn, 6);

	/* Remove MMIE */
	skb_trim(skb, skb->len - mmie_len);

	return RX_CONTINUE;
}

ieee80211_tx_result
ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb;
	struct ieee80211_tx_info *info;
	struct ieee80211_key *key = tx->key;
	struct ieee80211_mmie_16 *mmie;
	struct ieee80211_hdr *hdr;
	u8 aad[GMAC_AAD_LEN];
	u64 pn64;
	u8 nonce[GMAC_NONCE_LEN];

	if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
		return TX_DROP;

	skb = skb_peek(&tx->skbs);

	info = IEEE80211_SKB_CB(skb);

	if (info->control.hw_key &&
	    !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
		return TX_CONTINUE;

	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
		return TX_DROP;

	mmie = skb_put(skb, sizeof(*mmie));
	mmie->element_id = WLAN_EID_MMIE;
	mmie->length = sizeof(*mmie) - 2;
	mmie->key_id = cpu_to_le16(key->conf.keyidx);

	/* PN = PN + 1 */
	pn64 = atomic64_inc_return(&key->conf.tx_pn);

	bip_ipn_set64(mmie->sequence_number, pn64);

	if (info->control.hw_key)
		return TX_CONTINUE;

	bip_aad(skb, aad);

	hdr = (struct ieee80211_hdr *)skb->data;
	memcpy(nonce, hdr->addr2, ETH_ALEN);
	bip_ipn_swap(nonce + ETH_ALEN, mmie->sequence_number);

	/* MIC = AES-GMAC(IGTK, AAD || Management Frame Body || MMIE, 128) */
	if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
			       skb->data + 24, skb->len - 24, mmie->mic) < 0)
		return TX_DROP;

	return TX_CONTINUE;
}

ieee80211_rx_result
ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
{
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	struct ieee80211_key *key = rx->key;
	struct ieee80211_mmie_16 *mmie;
	u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;

	if (!ieee80211_is_mgmt(hdr->frame_control))
		return RX_CONTINUE;

	/* management frames are already linear */

	if (skb->len < 24 + sizeof(*mmie))
		return RX_DROP_U_SHORT_GMAC;

	mmie = (struct ieee80211_mmie_16 *)
		(skb->data + skb->len - sizeof(*mmie));
	if (mmie->element_id != WLAN_EID_MMIE ||
	    mmie->length != sizeof(*mmie) - 2)
		return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */

	bip_ipn_swap(ipn, mmie->sequence_number);

	if (memcmp(ipn, key->u.aes_gmac.rx_pn, 6) <= 0) {
		key->u.aes_gmac.replays++;
		return RX_DROP_U_REPLAY;
	}

	if (!(status->flag & RX_FLAG_DECRYPTED)) {
		/* hardware didn't decrypt/verify MIC */
		bip_aad(skb, aad);

		memcpy(nonce, hdr->addr2, ETH_ALEN);
		memcpy(nonce + ETH_ALEN, ipn, 6);

		mic = kmalloc(IEEE80211_GMAC_MIC_LEN, GFP_ATOMIC);
		if (!mic)
			return RX_DROP_U_OOM;
		if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
				       skb->data + 24, skb->len - 24,
				       mic) < 0 ||
		    crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
			key->u.aes_gmac.icverrors++;
			kfree(mic);
			return RX_DROP_U_MIC_FAIL;
		}
		kfree(mic);
	}

	memcpy(key->u.aes_gmac.rx_pn, ipn, 6);

	/* Remove MMIE */
	skb_trim(skb, skb->len - sizeof(*mmie));

	return RX_CONTINUE;
}
