/*
 * Copyright 2002-2004, Instant802 Networks, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/compiler.h>
#include <net/mac80211.h>

#include "ieee80211_i.h"
#include "michael.h"
#include "tkip.h"
#include "aes_ccm.h"
#include "wpa.h"

static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da,
				  u8 *qos_tid, u8 **data, size_t *data_len)
{
	struct ieee80211_hdr *hdr;
	size_t hdrlen;
	__le16 fc;

	hdr = (struct ieee80211_hdr *)skb->data;
	fc = hdr->frame_control;

	hdrlen = ieee80211_hdrlen(fc);

	*sa = ieee80211_get_SA(hdr);
	*da = ieee80211_get_DA(hdr);

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

	if (ieee80211_is_data_qos(fc))
		*qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80;
	else
		*qos_tid = 0;

	return skb->len < hdrlen ? -1 : 0;
}


ieee80211_tx_result
ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
{
	u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset;
	size_t data_len;
	u16 fc;
	struct sk_buff *skb = tx->skb;
	int authenticator;
	int wpa_test = 0;
	int tail;

	fc = tx->fc;

	if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
	    !WLAN_FC_DATA_PRESENT(fc))
		return TX_CONTINUE;

	if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len))
		return TX_DROP;

	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
	    !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
	    !wpa_test) {
		/* hwaccel - with no need for preallocated room for Michael MIC
		 */
		return TX_CONTINUE;
	}

	tail = MICHAEL_MIC_LEN;
	if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
		tail += TKIP_ICV_LEN;

	if (WARN_ON(skb_tailroom(skb) < tail ||
		    skb_headroom(skb) < TKIP_IV_LEN))
		return TX_DROP;

#if 0
	authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */
#else
	authenticator = 1;
#endif
	/* At this point we know we're using ALG_TKIP. To get the MIC key
	 * we now will rely on the offset from the ieee80211_key_conf::key */
	key_offset = authenticator ?
		NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY :
		NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
	key = &tx->key->conf.key[key_offset];
	mic = skb_put(skb, MICHAEL_MIC_LEN);
	michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
{
	u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset;
	size_t data_len;
	u16 fc;
	u8 mic[MICHAEL_MIC_LEN];
	struct sk_buff *skb = rx->skb;
	int authenticator = 1, wpa_test = 0;
	DECLARE_MAC_BUF(mac);

	fc = rx->fc;

	/*
	 * No way to verify the MIC if the hardware stripped it
	 */
	if (rx->status->flag & RX_FLAG_MMIC_STRIPPED)
		return RX_CONTINUE;

	if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
	    !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
		return RX_CONTINUE;

	if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)
	    || data_len < MICHAEL_MIC_LEN)
		return RX_DROP_UNUSABLE;

	data_len -= MICHAEL_MIC_LEN;

#if 0
	authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */
#else
	authenticator = 1;
#endif
	/* At this point we know we're using ALG_TKIP. To get the MIC key
	 * we now will rely on the offset from the ieee80211_key_conf::key */
	key_offset = authenticator ?
		NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
		NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
	key = &rx->key->conf.key[key_offset];
	michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
	if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
		if (!(rx->flags & IEEE80211_RX_RA_MATCH))
			return RX_DROP_UNUSABLE;

		mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
						(void *) skb->data);
		return RX_DROP_UNUSABLE;
	}

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

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

	return RX_CONTINUE;
}


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;
	u8 *pos;

	info->control.icv_len = TKIP_ICV_LEN;
	info->control.iv_len = TKIP_IV_LEN;

	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
		/* hwaccel - with no need for preallocated room for IV/ICV */
		info->control.hw_key = &tx->key->conf;
		return 0;
	}

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

	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
		tail = 0;
	else
		tail = TKIP_ICV_LEN;

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

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

	/* Increase IV for the frame */
	key->u.tkip.tx.iv16++;
	if (key->u.tkip.tx.iv16 == 0)
		key->u.tkip.tx.iv32++;

	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
		/* hwaccel - with preallocated room for IV */
		ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);

		info->control.hw_key = &tx->key->conf;
		return 0;
	}

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

	hdr = (struct ieee80211_hdr *) skb->data;
	ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
				    key, pos, len, hdr->addr2);
	return 0;
}


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

	ieee80211_tx_set_protected(tx);

	if (tkip_encrypt_skb(tx, skb) < 0)
		return TX_DROP;

	if (tx->extra_frag) {
		int i;
		for (i = 0; i < tx->num_extra_frag; i++) {
			if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 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, wpa_test = 0;
	struct ieee80211_key *key = rx->key;
	struct sk_buff *skb = rx->skb;
	DECLARE_MAC_BUF(mac);

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
		return RX_CONTINUE;

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

	if (rx->status->flag & RX_FLAG_DECRYPTED) {
		if (rx->status->flag & RX_FLAG_IV_STRIPPED) {
			/*
			 * Hardware took care of all processing, including
			 * replay protection, and stripped the ICV/IV so
			 * we cannot do any checks here.
			 */
			return RX_CONTINUE;
		}

		/* let TKIP code verify IV, but skip decryption */
		hwaccel = 1;
	}

	res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
					  key, skb->data + hdrlen,
					  skb->len - hdrlen, rx->sta->addr,
					  hdr->addr1, hwaccel, rx->queue,
					  &rx->tkip_iv32,
					  &rx->tkip_iv16);
	if (res != TKIP_DECRYPT_OK || wpa_test)
		return RX_DROP_UNUSABLE;

	/* Trim ICV */
	skb_trim(skb, skb->len - TKIP_ICV_LEN);

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

	return RX_CONTINUE;
}


static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
				int encrypted)
{
	u16 fc;
	int a4_included, qos_included;
	u8 qos_tid, *fc_pos, *data, *sa, *da;
	int len_a;
	size_t data_len;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;

	fc_pos = (u8 *) &hdr->frame_control;
	fc = fc_pos[0] ^ (fc_pos[1] << 8);
	a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
		(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);

	ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len);
	data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0);
	if (qos_tid & 0x80) {
		qos_included = 1;
		qos_tid &= 0x0f;
	} else
		qos_included = 0;
	/* First block, b_0 */

	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
	/* Nonce: QoS Priority | A2 | PN */
	b_0[1] = qos_tid;
	memcpy(&b_0[2], hdr->addr2, 6);
	memcpy(&b_0[8], pn, CCMP_PN_LEN);
	/* l(m) */
	b_0[14] = (data_len >> 8) & 0xff;
	b_0[15] = data_len & 0xff;


	/* AAD (extra authenticate-only data) / masked 802.11 header
	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */

	len_a = a4_included ? 28 : 22;
	if (qos_included)
		len_a += 2;

	aad[0] = 0; /* (len_a >> 8) & 0xff; */
	aad[1] = len_a & 0xff;
	/* Mask FC: zero subtype b4 b5 b6 */
	aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6));
	/* Retry, PwrMgt, MoreData; set Protected */
	aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6);
	memcpy(&aad[4], &hdr->addr1, 18);

	/* Mask Seq#, leave Frag# */
	aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
	aad[23] = 0;
	if (a4_included) {
		memcpy(&aad[24], hdr->addr4, 6);
		aad[30] = 0;
		aad[31] = 0;
	} else
		memset(&aad[24], 0, 8);
	if (qos_included) {
		u8 *dpos = &aad[a4_included ? 30 : 24];

		/* Mask QoS Control field */
		dpos[0] = qos_tid;
		dpos[1] = 0;
	}
}


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 int 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];
	return (hdr[3] >> 6) & 0x03;
}


static int ccmp_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, *pn, *b_0, *aad, *scratch;
	int i;

	info->control.icv_len = CCMP_MIC_LEN;
	info->control.iv_len = CCMP_HDR_LEN;

	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
		/* hwaccel - with no need for preallocated room for CCMP "
		 * header or MIC fields */
		info->control.hw_key = &tx->key->conf;
		return 0;
	}

	scratch = key->u.ccmp.tx_crypto_buf;
	b_0 = scratch + 3 * AES_BLOCK_LEN;
	aad = scratch + 4 * AES_BLOCK_LEN;

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

	if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
		tail = 0;
	else
		tail = CCMP_MIC_LEN;

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

	pos = skb_push(skb, CCMP_HDR_LEN);
	memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
	hdr = (struct ieee80211_hdr *) pos;
	pos += hdrlen;

	/* PN = PN + 1 */
	pn = key->u.ccmp.tx_pn;

	for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
		pn[i]++;
		if (pn[i])
			break;
	}

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

	if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
		/* hwaccel - with preallocated room for CCMP header */
		info->control.hw_key = &tx->key->conf;
		return 0;
	}

	pos += CCMP_HDR_LEN;
	ccmp_special_blocks(skb, pn, b_0, aad, 0);
	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, b_0, aad, pos, len,
				  pos, skb_put(skb, CCMP_MIC_LEN));

	return 0;
}


ieee80211_tx_result
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
{
	struct sk_buff *skb = tx->skb;

	ieee80211_tx_set_protected(tx);

	if (ccmp_encrypt_skb(tx, skb) < 0)
		return TX_DROP;

	if (tx->extra_frag) {
		int i;
		for (i = 0; i < tx->num_extra_frag; i++) {
			if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
				return TX_DROP;
		}
	}

	return TX_CONTINUE;
}


ieee80211_rx_result
ieee80211_crypto_ccmp_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;
	u8 pn[CCMP_PN_LEN];
	int data_len;
	DECLARE_MAC_BUF(mac);

	hdrlen = ieee80211_hdrlen(hdr->frame_control);

	if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
		return RX_CONTINUE;

	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
	if (!rx->sta || data_len < 0)
		return RX_DROP_UNUSABLE;

	if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
	    (rx->status->flag & RX_FLAG_IV_STRIPPED))
		return RX_CONTINUE;

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

	if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) {
		key->u.ccmp.replays++;
		return RX_DROP_UNUSABLE;
	}

	if (!(rx->status->flag & RX_FLAG_DECRYPTED)) {
		/* hardware didn't decrypt/verify MIC */
		u8 *scratch, *b_0, *aad;

		scratch = key->u.ccmp.rx_crypto_buf;
		b_0 = scratch + 3 * AES_BLOCK_LEN;
		aad = scratch + 4 * AES_BLOCK_LEN;

		ccmp_special_blocks(skb, pn, b_0, aad, 1);

		if (ieee80211_aes_ccm_decrypt(
			    key->u.ccmp.tfm, scratch, b_0, aad,
			    skb->data + hdrlen + CCMP_HDR_LEN, data_len,
			    skb->data + skb->len - CCMP_MIC_LEN,
			    skb->data + hdrlen + CCMP_HDR_LEN)) {
			return RX_DROP_UNUSABLE;
		}
	}

	memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN);

	/* Remove CCMP header and MIC */
	skb_trim(skb, skb->len - CCMP_MIC_LEN);
	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
	skb_pull(skb, CCMP_HDR_LEN);

	return RX_CONTINUE;
}
