/*
 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
 *
 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
 *
 * 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. See README and COPYING for
 * more details.
 */

#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/mm.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <asm/string.h>

#include <net/ieee80211.h>

#include <linux/crypto.h>
#include <linux/crc32.h>

MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: TKIP");
MODULE_LICENSE("GPL");

struct ieee80211_tkip_data {
#define TKIP_KEY_LEN 32
	u8 key[TKIP_KEY_LEN];
	int key_set;

	u32 tx_iv32;
	u16 tx_iv16;
	u16 tx_ttak[5];
	int tx_phase1_done;

	u32 rx_iv32;
	u16 rx_iv16;
	u16 rx_ttak[5];
	int rx_phase1_done;
	u32 rx_iv32_new;
	u16 rx_iv16_new;

	u32 dot11RSNAStatsTKIPReplays;
	u32 dot11RSNAStatsTKIPICVErrors;
	u32 dot11RSNAStatsTKIPLocalMICFailures;

	int key_idx;

	struct crypto_blkcipher *rx_tfm_arc4;
	struct crypto_hash *rx_tfm_michael;
	struct crypto_blkcipher *tx_tfm_arc4;
	struct crypto_hash *tx_tfm_michael;

	/* scratch buffers for virt_to_page() (crypto API) */
	u8 rx_hdr[16], tx_hdr[16];

	unsigned long flags;
};

static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
{
	struct ieee80211_tkip_data *_priv = priv;
	unsigned long old_flags = _priv->flags;
	_priv->flags = flags;
	return old_flags;
}

static unsigned long ieee80211_tkip_get_flags(void *priv)
{
	struct ieee80211_tkip_data *_priv = priv;
	return _priv->flags;
}

static void *ieee80211_tkip_init(int key_idx)
{
	struct ieee80211_tkip_data *priv;

	priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
	if (priv == NULL)
		goto fail;

	priv->key_idx = key_idx;

	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
						CRYPTO_ALG_ASYNC);
	if (IS_ERR(priv->tx_tfm_arc4)) {
		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
		       "crypto API arc4\n");
		priv->tx_tfm_arc4 = NULL;
		goto fail;
	}

	priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
						 CRYPTO_ALG_ASYNC);
	if (IS_ERR(priv->tx_tfm_michael)) {
		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
		       "crypto API michael_mic\n");
		priv->tx_tfm_michael = NULL;
		goto fail;
	}

	priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
						CRYPTO_ALG_ASYNC);
	if (IS_ERR(priv->rx_tfm_arc4)) {
		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
		       "crypto API arc4\n");
		priv->rx_tfm_arc4 = NULL;
		goto fail;
	}

	priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
						 CRYPTO_ALG_ASYNC);
	if (IS_ERR(priv->rx_tfm_michael)) {
		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
		       "crypto API michael_mic\n");
		priv->rx_tfm_michael = NULL;
		goto fail;
	}

	return priv;

      fail:
	if (priv) {
		if (priv->tx_tfm_michael)
			crypto_free_hash(priv->tx_tfm_michael);
		if (priv->tx_tfm_arc4)
			crypto_free_blkcipher(priv->tx_tfm_arc4);
		if (priv->rx_tfm_michael)
			crypto_free_hash(priv->rx_tfm_michael);
		if (priv->rx_tfm_arc4)
			crypto_free_blkcipher(priv->rx_tfm_arc4);
		kfree(priv);
	}

	return NULL;
}

static void ieee80211_tkip_deinit(void *priv)
{
	struct ieee80211_tkip_data *_priv = priv;
	if (_priv) {
		if (_priv->tx_tfm_michael)
			crypto_free_hash(_priv->tx_tfm_michael);
		if (_priv->tx_tfm_arc4)
			crypto_free_blkcipher(_priv->tx_tfm_arc4);
		if (_priv->rx_tfm_michael)
			crypto_free_hash(_priv->rx_tfm_michael);
		if (_priv->rx_tfm_arc4)
			crypto_free_blkcipher(_priv->rx_tfm_arc4);
	}
	kfree(priv);
}

static inline u16 RotR1(u16 val)
{
	return (val >> 1) | (val << 15);
}

static inline u8 Lo8(u16 val)
{
	return val & 0xff;
}

static inline u8 Hi8(u16 val)
{
	return val >> 8;
}

static inline u16 Lo16(u32 val)
{
	return val & 0xffff;
}

static inline u16 Hi16(u32 val)
{
	return val >> 16;
}

static inline u16 Mk16(u8 hi, u8 lo)
{
	return lo | (((u16) hi) << 8);
}

static inline u16 Mk16_le(u16 * v)
{
	return le16_to_cpu(*v);
}

static const u16 Sbox[256] = {
	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
};

static inline u16 _S_(u16 v)
{
	u16 t = Sbox[Hi8(v)];
	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
}

#define PHASE1_LOOP_COUNT 8

static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
			       u32 IV32)
{
	int i, j;

	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
	TTAK[0] = Lo16(IV32);
	TTAK[1] = Hi16(IV32);
	TTAK[2] = Mk16(TA[1], TA[0]);
	TTAK[3] = Mk16(TA[3], TA[2]);
	TTAK[4] = Mk16(TA[5], TA[4]);

	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
		j = 2 * (i & 1);
		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
	}
}

static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
			       u16 IV16)
{
	/* Make temporary area overlap WEP seed so that the final copy can be
	 * avoided on little endian hosts. */
	u16 *PPK = (u16 *) & WEPSeed[4];

	/* Step 1 - make copy of TTAK and bring in TSC */
	PPK[0] = TTAK[0];
	PPK[1] = TTAK[1];
	PPK[2] = TTAK[2];
	PPK[3] = TTAK[3];
	PPK[4] = TTAK[4];
	PPK[5] = TTAK[4] + IV16;

	/* Step 2 - 96-bit bijective mixing using S-box */
	PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
	PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
	PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
	PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
	PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
	PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));

	PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
	PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
	PPK[2] += RotR1(PPK[1]);
	PPK[3] += RotR1(PPK[2]);
	PPK[4] += RotR1(PPK[3]);
	PPK[5] += RotR1(PPK[4]);

	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
	 * WEPSeed[0..2] is transmitted as WEP IV */
	WEPSeed[0] = Hi8(IV16);
	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
	WEPSeed[2] = Lo8(IV16);
	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);

#ifdef __BIG_ENDIAN
	{
		int i;
		for (i = 0; i < 6; i++)
			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
	}
#endif
}

static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
			      u8 * rc4key, int keylen, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	int len;
	u8 *pos;
	struct ieee80211_hdr_4addr *hdr;

	hdr = (struct ieee80211_hdr_4addr *)skb->data;

	if (skb_headroom(skb) < 8 || skb->len < hdr_len)
		return -1;

	if (rc4key == NULL || keylen < 16)
		return -1;

	if (!tkey->tx_phase1_done) {
		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
				   tkey->tx_iv32);
		tkey->tx_phase1_done = 1;
	}
	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);

	len = skb->len - hdr_len;
	pos = skb_push(skb, 8);
	memmove(pos, pos + 8, hdr_len);
	pos += hdr_len;

	*pos++ = *rc4key;
	*pos++ = *(rc4key + 1);
	*pos++ = *(rc4key + 2);
	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
	*pos++ = tkey->tx_iv32 & 0xff;
	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
	*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
	*pos++ = (tkey->tx_iv32 >> 24) & 0xff;

	tkey->tx_iv16++;
	if (tkey->tx_iv16 == 0) {
		tkey->tx_phase1_done = 0;
		tkey->tx_iv32++;
	}

	return 8;
}

static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
	int len;
	u8 rc4key[16], *pos, *icv;
	u32 crc;
	struct scatterlist sg;
	DECLARE_MAC_BUF(mac);

	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
		if (net_ratelimit()) {
			struct ieee80211_hdr_4addr *hdr =
			    (struct ieee80211_hdr_4addr *)skb->data;
			printk(KERN_DEBUG ": TKIP countermeasures: dropped "
			       "TX packet to %s\n",
			       print_mac(mac, hdr->addr1));
		}
		return -1;
	}

	if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
		return -1;

	len = skb->len - hdr_len;
	pos = skb->data + hdr_len;

	if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
		return -1;

	icv = skb_put(skb, 4);

	crc = ~crc32_le(~0, pos, len);
	icv[0] = crc;
	icv[1] = crc >> 8;
	icv[2] = crc >> 16;
	icv[3] = crc >> 24;

	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
	sg_init_one(&sg, pos, len + 4);
	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
}

/*
 * deal with seq counter wrapping correctly.
 * refer to timer_after() for jiffies wrapping handling
 */
static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
				    u32 iv32_o, u16 iv16_o)
{
	if ((s32)iv32_n - (s32)iv32_o < 0 ||
	    (iv32_n == iv32_o && iv16_n <= iv16_o))
		return 1;
	return 0;
}

static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
	u8 rc4key[16];
	u8 keyidx, *pos;
	u32 iv32;
	u16 iv16;
	struct ieee80211_hdr_4addr *hdr;
	u8 icv[4];
	u32 crc;
	struct scatterlist sg;
	int plen;
	DECLARE_MAC_BUF(mac);

	hdr = (struct ieee80211_hdr_4addr *)skb->data;

	if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
		if (net_ratelimit()) {
			printk(KERN_DEBUG ": TKIP countermeasures: dropped "
			       "received packet from %s\n",
			       print_mac(mac, hdr->addr2));
		}
		return -1;
	}

	if (skb->len < hdr_len + 8 + 4)
		return -1;

	pos = skb->data + hdr_len;
	keyidx = pos[3];
	if (!(keyidx & (1 << 5))) {
		if (net_ratelimit()) {
			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
			       " flag from %s\n", print_mac(mac, hdr->addr2));
		}
		return -2;
	}
	keyidx >>= 6;
	if (tkey->key_idx != keyidx) {
		printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
		       "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
		return -6;
	}
	if (!tkey->key_set) {
		if (net_ratelimit()) {
			printk(KERN_DEBUG "TKIP: received packet from %s"
			       " with keyid=%d that does not have a configured"
			       " key\n", print_mac(mac, hdr->addr2), keyidx);
		}
		return -3;
	}
	iv16 = (pos[0] << 8) | pos[2];
	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
	pos += 8;

	if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
		if (net_ratelimit()) {
			IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%s"
			       " previous TSC %08x%04x received TSC "
			       "%08x%04x\n", print_mac(mac, hdr->addr2),
			       tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
		}
		tkey->dot11RSNAStatsTKIPReplays++;
		return -4;
	}

	if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
		tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
		tkey->rx_phase1_done = 1;
	}
	tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);

	plen = skb->len - hdr_len - 12;

	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
	sg_init_one(&sg, pos, plen + 4);
	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
		if (net_ratelimit()) {
			printk(KERN_DEBUG ": TKIP: failed to decrypt "
			       "received packet from %s\n",
			       print_mac(mac, hdr->addr2));
		}
		return -7;
	}

	crc = ~crc32_le(~0, pos, plen);
	icv[0] = crc;
	icv[1] = crc >> 8;
	icv[2] = crc >> 16;
	icv[3] = crc >> 24;
	if (memcmp(icv, pos + plen, 4) != 0) {
		if (iv32 != tkey->rx_iv32) {
			/* Previously cached Phase1 result was already lost, so
			 * it needs to be recalculated for the next packet. */
			tkey->rx_phase1_done = 0;
		}
		if (net_ratelimit()) {
			IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA="
			       "%s\n", print_mac(mac, hdr->addr2));
		}
		tkey->dot11RSNAStatsTKIPICVErrors++;
		return -5;
	}

	/* Update real counters only after Michael MIC verification has
	 * completed */
	tkey->rx_iv32_new = iv32;
	tkey->rx_iv16_new = iv16;

	/* Remove IV and ICV */
	memmove(skb->data + 8, skb->data, hdr_len);
	skb_pull(skb, 8);
	skb_trim(skb, skb->len - 4);

	return keyidx;
}

static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
		       u8 * data, size_t data_len, u8 * mic)
{
	struct hash_desc desc;
	struct scatterlist sg[2];

	if (tfm_michael == NULL) {
		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
		return -1;
	}
	sg_init_table(sg, 2);
	sg_set_buf(&sg[0], hdr, 16);
	sg_set_buf(&sg[1], data, data_len);

	if (crypto_hash_setkey(tfm_michael, key, 8))
		return -1;

	desc.tfm = tfm_michael;
	desc.flags = 0;
	return crypto_hash_digest(&desc, sg, data_len + 16, mic);
}

static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
{
	struct ieee80211_hdr_4addr *hdr11;
	u16 stype;

	hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
	stype  = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl));

	switch (le16_to_cpu(hdr11->frame_ctl) &
		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
	case IEEE80211_FCTL_TODS:
		memcpy(hdr, hdr11->addr3, ETH_ALEN);	/* DA */
		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN);	/* SA */
		break;
	case IEEE80211_FCTL_FROMDS:
		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN);	/* SA */
		break;
	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
		memcpy(hdr, hdr11->addr3, ETH_ALEN);	/* DA */
		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN);	/* SA */
		break;
	case 0:
		memcpy(hdr, hdr11->addr1, ETH_ALEN);	/* DA */
		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN);	/* SA */
		break;
	}

	if (stype & IEEE80211_STYPE_QOS_DATA) {
		const struct ieee80211_hdr_3addrqos *qoshdr =
			(struct ieee80211_hdr_3addrqos *)skb->data;
		hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
	} else
		hdr[12] = 0;		/* priority */

	hdr[13] = hdr[14] = hdr[15] = 0;	/* reserved */
}

static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
				     void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	u8 *pos;

	if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
		printk(KERN_DEBUG "Invalid packet for Michael MIC add "
		       "(tailroom=%d hdr_len=%d skb->len=%d)\n",
		       skb_tailroom(skb), hdr_len, skb->len);
		return -1;
	}

	michael_mic_hdr(skb, tkey->tx_hdr);
	pos = skb_put(skb, 8);
	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
			skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
		return -1;

	return 0;
}

static void ieee80211_michael_mic_failure(struct net_device *dev,
					  struct ieee80211_hdr_4addr *hdr,
					  int keyidx)
{
	union iwreq_data wrqu;
	struct iw_michaelmicfailure ev;

	/* TODO: needed parameters: count, keyid, key type, TSC */
	memset(&ev, 0, sizeof(ev));
	ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
	if (hdr->addr1[0] & 0x01)
		ev.flags |= IW_MICFAILURE_GROUP;
	else
		ev.flags |= IW_MICFAILURE_PAIRWISE;
	ev.src_addr.sa_family = ARPHRD_ETHER;
	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
	memset(&wrqu, 0, sizeof(wrqu));
	wrqu.data.length = sizeof(ev);
	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}

static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
					int hdr_len, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	u8 mic[8];
	DECLARE_MAC_BUF(mac);

	if (!tkey->key_set)
		return -1;

	michael_mic_hdr(skb, tkey->rx_hdr);
	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
		return -1;
	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
		struct ieee80211_hdr_4addr *hdr;
		hdr = (struct ieee80211_hdr_4addr *)skb->data;
		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
		       "MSDU from %s keyidx=%d\n",
		       skb->dev ? skb->dev->name : "N/A", print_mac(mac, hdr->addr2),
		       keyidx);
		if (skb->dev)
			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
		return -1;
	}

	/* Update TSC counters for RX now that the packet verification has
	 * completed. */
	tkey->rx_iv32 = tkey->rx_iv32_new;
	tkey->rx_iv16 = tkey->rx_iv16_new;

	skb_trim(skb, skb->len - 8);

	return 0;
}

static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;
	int keyidx;
	struct crypto_hash *tfm = tkey->tx_tfm_michael;
	struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
	struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
	struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;

	keyidx = tkey->key_idx;
	memset(tkey, 0, sizeof(*tkey));
	tkey->key_idx = keyidx;
	tkey->tx_tfm_michael = tfm;
	tkey->tx_tfm_arc4 = tfm2;
	tkey->rx_tfm_michael = tfm3;
	tkey->rx_tfm_arc4 = tfm4;
	if (len == TKIP_KEY_LEN) {
		memcpy(tkey->key, key, TKIP_KEY_LEN);
		tkey->key_set = 1;
		tkey->tx_iv16 = 1;	/* TSC is initialized to 1 */
		if (seq) {
			tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
			    (seq[3] << 8) | seq[2];
			tkey->rx_iv16 = (seq[1] << 8) | seq[0];
		}
	} else if (len == 0)
		tkey->key_set = 0;
	else
		return -1;

	return 0;
}

static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
{
	struct ieee80211_tkip_data *tkey = priv;

	if (len < TKIP_KEY_LEN)
		return -1;

	if (!tkey->key_set)
		return 0;
	memcpy(key, tkey->key, TKIP_KEY_LEN);

	if (seq) {
		/* Return the sequence number of the last transmitted frame. */
		u16 iv16 = tkey->tx_iv16;
		u32 iv32 = tkey->tx_iv32;
		if (iv16 == 0)
			iv32--;
		iv16--;
		seq[0] = tkey->tx_iv16;
		seq[1] = tkey->tx_iv16 >> 8;
		seq[2] = tkey->tx_iv32;
		seq[3] = tkey->tx_iv32 >> 8;
		seq[4] = tkey->tx_iv32 >> 16;
		seq[5] = tkey->tx_iv32 >> 24;
	}

	return TKIP_KEY_LEN;
}

static char *ieee80211_tkip_print_stats(char *p, void *priv)
{
	struct ieee80211_tkip_data *tkip = priv;
	p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
		     "tx_pn=%02x%02x%02x%02x%02x%02x "
		     "rx_pn=%02x%02x%02x%02x%02x%02x "
		     "replays=%d icv_errors=%d local_mic_failures=%d\n",
		     tkip->key_idx, tkip->key_set,
		     (tkip->tx_iv32 >> 24) & 0xff,
		     (tkip->tx_iv32 >> 16) & 0xff,
		     (tkip->tx_iv32 >> 8) & 0xff,
		     tkip->tx_iv32 & 0xff,
		     (tkip->tx_iv16 >> 8) & 0xff,
		     tkip->tx_iv16 & 0xff,
		     (tkip->rx_iv32 >> 24) & 0xff,
		     (tkip->rx_iv32 >> 16) & 0xff,
		     (tkip->rx_iv32 >> 8) & 0xff,
		     tkip->rx_iv32 & 0xff,
		     (tkip->rx_iv16 >> 8) & 0xff,
		     tkip->rx_iv16 & 0xff,
		     tkip->dot11RSNAStatsTKIPReplays,
		     tkip->dot11RSNAStatsTKIPICVErrors,
		     tkip->dot11RSNAStatsTKIPLocalMICFailures);
	return p;
}

static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
	.name = "TKIP",
	.init = ieee80211_tkip_init,
	.deinit = ieee80211_tkip_deinit,
	.build_iv = ieee80211_tkip_hdr,
	.encrypt_mpdu = ieee80211_tkip_encrypt,
	.decrypt_mpdu = ieee80211_tkip_decrypt,
	.encrypt_msdu = ieee80211_michael_mic_add,
	.decrypt_msdu = ieee80211_michael_mic_verify,
	.set_key = ieee80211_tkip_set_key,
	.get_key = ieee80211_tkip_get_key,
	.print_stats = ieee80211_tkip_print_stats,
	.extra_mpdu_prefix_len = 4 + 4,	/* IV + ExtIV */
	.extra_mpdu_postfix_len = 4,	/* ICV */
	.extra_msdu_postfix_len = 8,	/* MIC */
	.get_flags = ieee80211_tkip_get_flags,
	.set_flags = ieee80211_tkip_set_flags,
	.owner = THIS_MODULE,
};

static int __init ieee80211_crypto_tkip_init(void)
{
	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
}

static void __exit ieee80211_crypto_tkip_exit(void)
{
	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
}

module_init(ieee80211_crypto_tkip_init);
module_exit(ieee80211_crypto_tkip_exit);
