Home | History | Annotate | Line # | Download | only in net80211
ieee80211_crypto_tkip.c revision 1.3.6.2
      1  1.3.6.2  skrll /*-
      2  1.3.6.2  skrll  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
      3  1.3.6.2  skrll  * All rights reserved.
      4  1.3.6.2  skrll  *
      5  1.3.6.2  skrll  * Redistribution and use in source and binary forms, with or without
      6  1.3.6.2  skrll  * modification, are permitted provided that the following conditions
      7  1.3.6.2  skrll  * are met:
      8  1.3.6.2  skrll  * 1. Redistributions of source code must retain the above copyright
      9  1.3.6.2  skrll  *    notice, this list of conditions and the following disclaimer.
     10  1.3.6.2  skrll  * 2. Redistributions in binary form must reproduce the above copyright
     11  1.3.6.2  skrll  *    notice, this list of conditions and the following disclaimer in the
     12  1.3.6.2  skrll  *    documentation and/or other materials provided with the distribution.
     13  1.3.6.2  skrll  * 3. The name of the author may not be used to endorse or promote products
     14  1.3.6.2  skrll  *    derived from this software without specific prior written permission.
     15  1.3.6.2  skrll  *
     16  1.3.6.2  skrll  * Alternatively, this software may be distributed under the terms of the
     17  1.3.6.2  skrll  * GNU General Public License ("GPL") version 2 as published by the Free
     18  1.3.6.2  skrll  * Software Foundation.
     19  1.3.6.2  skrll  *
     20  1.3.6.2  skrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  1.3.6.2  skrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  1.3.6.2  skrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  1.3.6.2  skrll  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  1.3.6.2  skrll  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  1.3.6.2  skrll  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  1.3.6.2  skrll  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  1.3.6.2  skrll  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  1.3.6.2  skrll  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  1.3.6.2  skrll  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  1.3.6.2  skrll  */
     31  1.3.6.2  skrll 
     32  1.3.6.2  skrll #include <sys/cdefs.h>
     33  1.3.6.2  skrll #ifdef __FreeBSD__
     34  1.3.6.2  skrll __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.9 2005/06/10 16:11:24 sam Exp $");
     35  1.3.6.2  skrll #endif
     36  1.3.6.2  skrll #ifdef __NetBSD__
     37  1.3.6.2  skrll __KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.3.6.2 2005/11/10 14:10:51 skrll Exp $");
     38  1.3.6.2  skrll #endif
     39  1.3.6.2  skrll 
     40  1.3.6.2  skrll /*
     41  1.3.6.2  skrll  * IEEE 802.11i TKIP crypto support.
     42  1.3.6.2  skrll  *
     43  1.3.6.2  skrll  * Part of this module is derived from similar code in the Host
     44  1.3.6.2  skrll  * AP driver. The code is used with the consent of the author and
     45  1.3.6.2  skrll  * it's license is included below.
     46  1.3.6.2  skrll  */
     47  1.3.6.2  skrll #include <sys/param.h>
     48  1.3.6.2  skrll #include <sys/systm.h>
     49  1.3.6.2  skrll #include <sys/mbuf.h>
     50  1.3.6.2  skrll #include <sys/malloc.h>
     51  1.3.6.2  skrll #include <sys/kernel.h>
     52  1.3.6.2  skrll #include <sys/endian.h>
     53  1.3.6.2  skrll 
     54  1.3.6.2  skrll #include <sys/socket.h>
     55  1.3.6.2  skrll 
     56  1.3.6.2  skrll #include <net/if.h>
     57  1.3.6.2  skrll #include <net/if_media.h>
     58  1.3.6.2  skrll 
     59  1.3.6.2  skrll #include <net80211/ieee80211_var.h>
     60  1.3.6.2  skrll 
     61  1.3.6.2  skrll static	void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
     62  1.3.6.2  skrll static	void tkip_detach(struct ieee80211_key *);
     63  1.3.6.2  skrll static	int tkip_setkey(struct ieee80211_key *);
     64  1.3.6.2  skrll static	int tkip_encap(struct ieee80211_key *, struct mbuf *m, u_int8_t keyid);
     65  1.3.6.2  skrll static	int tkip_enmic(struct ieee80211_key *, struct mbuf *, int);
     66  1.3.6.2  skrll static	int tkip_decap(struct ieee80211_key *, struct mbuf *, int);
     67  1.3.6.2  skrll static	int tkip_demic(struct ieee80211_key *, struct mbuf *, int);
     68  1.3.6.2  skrll 
     69  1.3.6.2  skrll const struct ieee80211_cipher ieee80211_cipher_tkip  = {
     70  1.3.6.2  skrll 	.ic_name	= "TKIP",
     71  1.3.6.2  skrll 	.ic_cipher	= IEEE80211_CIPHER_TKIP,
     72  1.3.6.2  skrll 	.ic_header	= IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
     73  1.3.6.2  skrll 			  IEEE80211_WEP_EXTIVLEN,
     74  1.3.6.2  skrll 	.ic_trailer	= IEEE80211_WEP_CRCLEN,
     75  1.3.6.2  skrll 	.ic_miclen	= IEEE80211_WEP_MICLEN,
     76  1.3.6.2  skrll 	.ic_attach	= tkip_attach,
     77  1.3.6.2  skrll 	.ic_detach	= tkip_detach,
     78  1.3.6.2  skrll 	.ic_setkey	= tkip_setkey,
     79  1.3.6.2  skrll 	.ic_encap	= tkip_encap,
     80  1.3.6.2  skrll 	.ic_decap	= tkip_decap,
     81  1.3.6.2  skrll 	.ic_enmic	= tkip_enmic,
     82  1.3.6.2  skrll 	.ic_demic	= tkip_demic,
     83  1.3.6.2  skrll };
     84  1.3.6.2  skrll 
     85  1.3.6.2  skrll #define	tkip	ieee80211_cipher_tkip
     86  1.3.6.2  skrll 
     87  1.3.6.2  skrll typedef	uint8_t u8;
     88  1.3.6.2  skrll typedef	uint16_t u16;
     89  1.3.6.2  skrll typedef	uint32_t __u32;
     90  1.3.6.2  skrll typedef	uint32_t u32;
     91  1.3.6.2  skrll 
     92  1.3.6.2  skrll struct tkip_ctx {
     93  1.3.6.2  skrll 	struct ieee80211com *tc_ic;	/* for diagnostics */
     94  1.3.6.2  skrll 
     95  1.3.6.2  skrll 	u16	tx_ttak[5];
     96  1.3.6.2  skrll 	int	tx_phase1_done;
     97  1.3.6.2  skrll 	u8	tx_rc4key[16];		/* XXX for test module; make locals? */
     98  1.3.6.2  skrll 
     99  1.3.6.2  skrll 	u16	rx_ttak[5];
    100  1.3.6.2  skrll 	int	rx_phase1_done;
    101  1.3.6.2  skrll 	u8	rx_rc4key[16];		/* XXX for test module; make locals? */
    102  1.3.6.2  skrll 	uint64_t rx_rsc;		/* held until MIC verified */
    103  1.3.6.2  skrll };
    104  1.3.6.2  skrll 
    105  1.3.6.2  skrll static	void michael_mic(struct tkip_ctx *, const u8 *key,
    106  1.3.6.2  skrll 		struct mbuf *m, u_int off, size_t data_len,
    107  1.3.6.2  skrll 		u8 mic[IEEE80211_WEP_MICLEN]);
    108  1.3.6.2  skrll static	int tkip_encrypt(struct tkip_ctx *, struct ieee80211_key *,
    109  1.3.6.2  skrll 		struct mbuf *, int hdr_len);
    110  1.3.6.2  skrll static	int tkip_decrypt(struct tkip_ctx *, struct ieee80211_key *,
    111  1.3.6.2  skrll 		struct mbuf *, int hdr_len);
    112  1.3.6.2  skrll 
    113  1.3.6.2  skrll static void *
    114  1.3.6.2  skrll tkip_attach(struct ieee80211com *ic, struct ieee80211_key *k)
    115  1.3.6.2  skrll {
    116  1.3.6.2  skrll 	struct tkip_ctx *ctx;
    117  1.3.6.2  skrll 
    118  1.3.6.2  skrll 	MALLOC(ctx, struct tkip_ctx *, sizeof(struct tkip_ctx),
    119  1.3.6.2  skrll 		M_DEVBUF, M_NOWAIT | M_ZERO);
    120  1.3.6.2  skrll 	if (ctx == NULL) {
    121  1.3.6.2  skrll 		ic->ic_stats.is_crypto_nomem++;
    122  1.3.6.2  skrll 		return NULL;
    123  1.3.6.2  skrll 	}
    124  1.3.6.2  skrll 
    125  1.3.6.2  skrll 	ctx->tc_ic = ic;
    126  1.3.6.2  skrll 	return ctx;
    127  1.3.6.2  skrll }
    128  1.3.6.2  skrll 
    129  1.3.6.2  skrll static void
    130  1.3.6.2  skrll tkip_detach(struct ieee80211_key *k)
    131  1.3.6.2  skrll {
    132  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    133  1.3.6.2  skrll 
    134  1.3.6.2  skrll 	FREE(ctx, M_DEVBUF);
    135  1.3.6.2  skrll }
    136  1.3.6.2  skrll 
    137  1.3.6.2  skrll static int
    138  1.3.6.2  skrll tkip_setkey(struct ieee80211_key *k)
    139  1.3.6.2  skrll {
    140  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    141  1.3.6.2  skrll 
    142  1.3.6.2  skrll 	if (k->wk_keylen != (128/NBBY)) {
    143  1.3.6.2  skrll 		(void) ctx;		/* XXX */
    144  1.3.6.2  skrll 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
    145  1.3.6.2  skrll 			"%s: Invalid key length %u, expecting %u\n",
    146  1.3.6.2  skrll 			__func__, k->wk_keylen, 128/NBBY);
    147  1.3.6.2  skrll 		return 0;
    148  1.3.6.2  skrll 	}
    149  1.3.6.2  skrll 	k->wk_keytsc = 1;		/* TSC starts at 1 */
    150  1.3.6.2  skrll 	return 1;
    151  1.3.6.2  skrll }
    152  1.3.6.2  skrll 
    153  1.3.6.2  skrll /*
    154  1.3.6.2  skrll  * Add privacy headers and do any s/w encryption required.
    155  1.3.6.2  skrll  */
    156  1.3.6.2  skrll static int
    157  1.3.6.2  skrll tkip_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
    158  1.3.6.2  skrll {
    159  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    160  1.3.6.2  skrll 	struct ieee80211com *ic = ctx->tc_ic;
    161  1.3.6.2  skrll 	u_int8_t *ivp;
    162  1.3.6.2  skrll 	int hdrlen;
    163  1.3.6.2  skrll 
    164  1.3.6.2  skrll 	/*
    165  1.3.6.2  skrll 	 * Handle TKIP counter measures requirement.
    166  1.3.6.2  skrll 	 */
    167  1.3.6.2  skrll 	if (ic->ic_flags & IEEE80211_F_COUNTERM) {
    168  1.3.6.2  skrll #ifdef IEEE80211_DEBUG
    169  1.3.6.2  skrll 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
    170  1.3.6.2  skrll #endif
    171  1.3.6.2  skrll 
    172  1.3.6.2  skrll 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
    173  1.3.6.2  skrll 			"[%s] Discard frame due to countermeasures (%s)\n",
    174  1.3.6.2  skrll 			ether_sprintf(wh->i_addr2), __func__);
    175  1.3.6.2  skrll 		ic->ic_stats.is_crypto_tkipcm++;
    176  1.3.6.2  skrll 		return 0;
    177  1.3.6.2  skrll 	}
    178  1.3.6.2  skrll 	hdrlen = ieee80211_hdrspace(ic, mtod(m, void *));
    179  1.3.6.2  skrll 
    180  1.3.6.2  skrll 	/*
    181  1.3.6.2  skrll 	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
    182  1.3.6.2  skrll 	 */
    183  1.3.6.2  skrll 	M_PREPEND(m, tkip.ic_header, M_NOWAIT);
    184  1.3.6.2  skrll 	if (m == NULL)
    185  1.3.6.2  skrll 		return 0;
    186  1.3.6.2  skrll 	ivp = mtod(m, u_int8_t *);
    187  1.3.6.2  skrll 	memmove(ivp, ivp + tkip.ic_header, hdrlen);
    188  1.3.6.2  skrll 	ivp += hdrlen;
    189  1.3.6.2  skrll 
    190  1.3.6.2  skrll 	ivp[0] = k->wk_keytsc >> 8;		/* TSC1 */
    191  1.3.6.2  skrll 	ivp[1] = (ivp[0] | 0x20) & 0x7f;	/* WEP seed */
    192  1.3.6.2  skrll 	ivp[2] = k->wk_keytsc >> 0;		/* TSC0 */
    193  1.3.6.2  skrll 	ivp[3] = keyid | IEEE80211_WEP_EXTIV;	/* KeyID | ExtID */
    194  1.3.6.2  skrll 	ivp[4] = k->wk_keytsc >> 16;		/* TSC2 */
    195  1.3.6.2  skrll 	ivp[5] = k->wk_keytsc >> 24;		/* TSC3 */
    196  1.3.6.2  skrll 	ivp[6] = k->wk_keytsc >> 32;		/* TSC4 */
    197  1.3.6.2  skrll 	ivp[7] = k->wk_keytsc >> 40;		/* TSC5 */
    198  1.3.6.2  skrll 
    199  1.3.6.2  skrll 	/*
    200  1.3.6.2  skrll 	 * Finally, do software encrypt if neeed.
    201  1.3.6.2  skrll 	 */
    202  1.3.6.2  skrll 	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
    203  1.3.6.2  skrll 		if (!tkip_encrypt(ctx, k, m, hdrlen))
    204  1.3.6.2  skrll 			return 0;
    205  1.3.6.2  skrll 		/* NB: tkip_encrypt handles wk_keytsc */
    206  1.3.6.2  skrll 	} else
    207  1.3.6.2  skrll 		k->wk_keytsc++;
    208  1.3.6.2  skrll 
    209  1.3.6.2  skrll 	return 1;
    210  1.3.6.2  skrll }
    211  1.3.6.2  skrll 
    212  1.3.6.2  skrll /*
    213  1.3.6.2  skrll  * Add MIC to the frame as needed.
    214  1.3.6.2  skrll  */
    215  1.3.6.2  skrll static int
    216  1.3.6.2  skrll tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
    217  1.3.6.2  skrll {
    218  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    219  1.3.6.2  skrll 
    220  1.3.6.2  skrll 	if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
    221  1.3.6.2  skrll 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
    222  1.3.6.2  skrll 		struct ieee80211com *ic = ctx->tc_ic;
    223  1.3.6.2  skrll 		int hdrlen;
    224  1.3.6.2  skrll 		uint8_t mic[IEEE80211_WEP_MICLEN];
    225  1.3.6.2  skrll 
    226  1.3.6.2  skrll 		ic->ic_stats.is_crypto_tkipenmic++;
    227  1.3.6.2  skrll 
    228  1.3.6.2  skrll 		hdrlen = ieee80211_hdrspace(ic, wh);
    229  1.3.6.2  skrll 
    230  1.3.6.2  skrll 		michael_mic(ctx, k->wk_txmic,
    231  1.3.6.2  skrll 			m, hdrlen, m->m_pkthdr.len - hdrlen, mic);
    232  1.3.6.2  skrll 		return m_append(m, tkip.ic_miclen, mic);
    233  1.3.6.2  skrll 	}
    234  1.3.6.2  skrll 	return 1;
    235  1.3.6.2  skrll }
    236  1.3.6.2  skrll 
    237  1.3.6.2  skrll static __inline uint64_t
    238  1.3.6.2  skrll READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
    239  1.3.6.2  skrll {
    240  1.3.6.2  skrll 	uint32_t iv32 = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24);
    241  1.3.6.2  skrll 	uint16_t iv16 = (b4 << 0) | (b5 << 8);
    242  1.3.6.2  skrll 	return (((uint64_t)iv16) << 32) | iv32;
    243  1.3.6.2  skrll }
    244  1.3.6.2  skrll 
    245  1.3.6.2  skrll /*
    246  1.3.6.2  skrll  * Validate and strip privacy headers (and trailer) for a
    247  1.3.6.2  skrll  * received frame.  If necessary, decrypt the frame using
    248  1.3.6.2  skrll  * the specified key.
    249  1.3.6.2  skrll  */
    250  1.3.6.2  skrll static int
    251  1.3.6.2  skrll tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
    252  1.3.6.2  skrll {
    253  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    254  1.3.6.2  skrll 	struct ieee80211com *ic = ctx->tc_ic;
    255  1.3.6.2  skrll 	struct ieee80211_frame *wh;
    256  1.3.6.2  skrll 	uint8_t *ivp;
    257  1.3.6.2  skrll 
    258  1.3.6.2  skrll 	/*
    259  1.3.6.2  skrll 	 * Header should have extended IV and sequence number;
    260  1.3.6.2  skrll 	 * verify the former and validate the latter.
    261  1.3.6.2  skrll 	 */
    262  1.3.6.2  skrll 	wh = mtod(m, struct ieee80211_frame *);
    263  1.3.6.2  skrll 	ivp = mtod(m, uint8_t *) + hdrlen;
    264  1.3.6.2  skrll 	if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
    265  1.3.6.2  skrll 		/*
    266  1.3.6.2  skrll 		 * No extended IV; discard frame.
    267  1.3.6.2  skrll 		 */
    268  1.3.6.2  skrll 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
    269  1.3.6.2  skrll 			"[%s] missing ExtIV for TKIP cipher\n",
    270  1.3.6.2  skrll 			ether_sprintf(wh->i_addr2));
    271  1.3.6.2  skrll 		ctx->tc_ic->ic_stats.is_rx_tkipformat++;
    272  1.3.6.2  skrll 		return 0;
    273  1.3.6.2  skrll 	}
    274  1.3.6.2  skrll 	/*
    275  1.3.6.2  skrll 	 * Handle TKIP counter measures requirement.
    276  1.3.6.2  skrll 	 */
    277  1.3.6.2  skrll 	if (ic->ic_flags & IEEE80211_F_COUNTERM) {
    278  1.3.6.2  skrll 		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
    279  1.3.6.2  skrll 			"[%s] discard frame due to countermeasures (%s)\n",
    280  1.3.6.2  skrll 			ether_sprintf(wh->i_addr2), __func__);
    281  1.3.6.2  skrll 		ic->ic_stats.is_crypto_tkipcm++;
    282  1.3.6.2  skrll 		return 0;
    283  1.3.6.2  skrll 	}
    284  1.3.6.2  skrll 
    285  1.3.6.2  skrll 	ctx->rx_rsc = READ_6(ivp[2], ivp[0], ivp[4], ivp[5], ivp[6], ivp[7]);
    286  1.3.6.2  skrll 	if (ctx->rx_rsc <= k->wk_keyrsc) {
    287  1.3.6.2  skrll 		/*
    288  1.3.6.2  skrll 		 * Replay violation; notify upper layer.
    289  1.3.6.2  skrll 		 */
    290  1.3.6.2  skrll 		ieee80211_notify_replay_failure(ctx->tc_ic, wh, k, ctx->rx_rsc);
    291  1.3.6.2  skrll 		ctx->tc_ic->ic_stats.is_rx_tkipreplay++;
    292  1.3.6.2  skrll 		return 0;
    293  1.3.6.2  skrll 	}
    294  1.3.6.2  skrll 	/*
    295  1.3.6.2  skrll 	 * NB: We can't update the rsc in the key until MIC is verified.
    296  1.3.6.2  skrll 	 *
    297  1.3.6.2  skrll 	 * We assume we are not preempted between doing the check above
    298  1.3.6.2  skrll 	 * and updating wk_keyrsc when stripping the MIC in tkip_demic.
    299  1.3.6.2  skrll 	 * Otherwise we might process another packet and discard it as
    300  1.3.6.2  skrll 	 * a replay.
    301  1.3.6.2  skrll 	 */
    302  1.3.6.2  skrll 
    303  1.3.6.2  skrll 	/*
    304  1.3.6.2  skrll 	 * Check if the device handled the decrypt in hardware.
    305  1.3.6.2  skrll 	 * If so we just strip the header; otherwise we need to
    306  1.3.6.2  skrll 	 * handle the decrypt in software.
    307  1.3.6.2  skrll 	 */
    308  1.3.6.2  skrll 	if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
    309  1.3.6.2  skrll 	    !tkip_decrypt(ctx, k, m, hdrlen))
    310  1.3.6.2  skrll 		return 0;
    311  1.3.6.2  skrll 
    312  1.3.6.2  skrll 	/*
    313  1.3.6.2  skrll 	 * Copy up 802.11 header and strip crypto bits.
    314  1.3.6.2  skrll 	 */
    315  1.3.6.2  skrll 	memmove(mtod(m, uint8_t *) + tkip.ic_header, mtod(m, void *), hdrlen);
    316  1.3.6.2  skrll 	m_adj(m, tkip.ic_header);
    317  1.3.6.2  skrll 	m_adj(m, -tkip.ic_trailer);
    318  1.3.6.2  skrll 
    319  1.3.6.2  skrll 	return 1;
    320  1.3.6.2  skrll }
    321  1.3.6.2  skrll 
    322  1.3.6.2  skrll /*
    323  1.3.6.2  skrll  * Verify and strip MIC from the frame.
    324  1.3.6.2  skrll  */
    325  1.3.6.2  skrll static int
    326  1.3.6.2  skrll tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
    327  1.3.6.2  skrll {
    328  1.3.6.2  skrll 	struct tkip_ctx *ctx = k->wk_private;
    329  1.3.6.2  skrll 
    330  1.3.6.2  skrll 	if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
    331  1.3.6.2  skrll 		struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
    332  1.3.6.2  skrll 		struct ieee80211com *ic = ctx->tc_ic;
    333  1.3.6.2  skrll 		int hdrlen = ieee80211_hdrspace(ic, wh);
    334  1.3.6.2  skrll 		u8 mic[IEEE80211_WEP_MICLEN];
    335  1.3.6.2  skrll 		u8 mic0[IEEE80211_WEP_MICLEN];
    336  1.3.6.2  skrll 
    337  1.3.6.2  skrll 		ic->ic_stats.is_crypto_tkipdemic++;
    338  1.3.6.2  skrll 
    339  1.3.6.2  skrll 		michael_mic(ctx, k->wk_rxmic,
    340  1.3.6.2  skrll 			m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen),
    341  1.3.6.2  skrll 			mic);
    342  1.3.6.2  skrll 		m_copydata(m, m->m_pkthdr.len - tkip.ic_miclen,
    343  1.3.6.2  skrll 			tkip.ic_miclen, mic0);
    344  1.3.6.2  skrll 		if (memcmp(mic, mic0, tkip.ic_miclen)) {
    345  1.3.6.2  skrll 			/* NB: 802.11 layer handles statistic and debug msg */
    346  1.3.6.2  skrll 			ieee80211_notify_michael_failure(ic, wh, k->wk_keyix);
    347  1.3.6.2  skrll 			return 0;
    348  1.3.6.2  skrll 		}
    349  1.3.6.2  skrll 	}
    350  1.3.6.2  skrll 	/*
    351  1.3.6.2  skrll 	 * Strip MIC from the tail.
    352  1.3.6.2  skrll 	 */
    353  1.3.6.2  skrll 	m_adj(m, -tkip.ic_miclen);
    354  1.3.6.2  skrll 
    355  1.3.6.2  skrll 	/*
    356  1.3.6.2  skrll 	 * Ok to update rsc now that MIC has been verified.
    357  1.3.6.2  skrll 	 */
    358  1.3.6.2  skrll 	k->wk_keyrsc = ctx->rx_rsc;
    359  1.3.6.2  skrll 
    360  1.3.6.2  skrll 	return 1;
    361  1.3.6.2  skrll }
    362  1.3.6.2  skrll 
    363  1.3.6.2  skrll /*
    364  1.3.6.2  skrll  * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
    365  1.3.6.2  skrll  *
    366  1.3.6.2  skrll  * Copyright (c) 2003-2004, Jouni Malinen <jkmaline (at) cc.hut.fi>
    367  1.3.6.2  skrll  *
    368  1.3.6.2  skrll  * This program is free software; you can redistribute it and/or modify
    369  1.3.6.2  skrll  * it under the terms of the GNU General Public License version 2 as
    370  1.3.6.2  skrll  * published by the Free Software Foundation. See README and COPYING for
    371  1.3.6.2  skrll  * more details.
    372  1.3.6.2  skrll  *
    373  1.3.6.2  skrll  * Alternatively, this software may be distributed under the terms of BSD
    374  1.3.6.2  skrll  * license.
    375  1.3.6.2  skrll  */
    376  1.3.6.2  skrll 
    377  1.3.6.2  skrll static const __u32 crc32_table[256] = {
    378  1.3.6.2  skrll 	0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
    379  1.3.6.2  skrll 	0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
    380  1.3.6.2  skrll 	0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
    381  1.3.6.2  skrll 	0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
    382  1.3.6.2  skrll 	0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
    383  1.3.6.2  skrll 	0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
    384  1.3.6.2  skrll 	0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
    385  1.3.6.2  skrll 	0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
    386  1.3.6.2  skrll 	0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
    387  1.3.6.2  skrll 	0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
    388  1.3.6.2  skrll 	0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
    389  1.3.6.2  skrll 	0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
    390  1.3.6.2  skrll 	0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
    391  1.3.6.2  skrll 	0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
    392  1.3.6.2  skrll 	0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
    393  1.3.6.2  skrll 	0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
    394  1.3.6.2  skrll 	0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
    395  1.3.6.2  skrll 	0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
    396  1.3.6.2  skrll 	0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
    397  1.3.6.2  skrll 	0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
    398  1.3.6.2  skrll 	0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
    399  1.3.6.2  skrll 	0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
    400  1.3.6.2  skrll 	0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
    401  1.3.6.2  skrll 	0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
    402  1.3.6.2  skrll 	0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
    403  1.3.6.2  skrll 	0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
    404  1.3.6.2  skrll 	0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
    405  1.3.6.2  skrll 	0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
    406  1.3.6.2  skrll 	0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
    407  1.3.6.2  skrll 	0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
    408  1.3.6.2  skrll 	0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
    409  1.3.6.2  skrll 	0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
    410  1.3.6.2  skrll 	0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
    411  1.3.6.2  skrll 	0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
    412  1.3.6.2  skrll 	0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
    413  1.3.6.2  skrll 	0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
    414  1.3.6.2  skrll 	0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
    415  1.3.6.2  skrll 	0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
    416  1.3.6.2  skrll 	0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
    417  1.3.6.2  skrll 	0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
    418  1.3.6.2  skrll 	0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
    419  1.3.6.2  skrll 	0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
    420  1.3.6.2  skrll 	0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
    421  1.3.6.2  skrll 	0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
    422  1.3.6.2  skrll 	0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
    423  1.3.6.2  skrll 	0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
    424  1.3.6.2  skrll 	0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
    425  1.3.6.2  skrll 	0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
    426  1.3.6.2  skrll 	0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
    427  1.3.6.2  skrll 	0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
    428  1.3.6.2  skrll 	0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
    429  1.3.6.2  skrll 	0x2d02ef8dL
    430  1.3.6.2  skrll };
    431  1.3.6.2  skrll 
    432  1.3.6.2  skrll static __inline u16 RotR1(u16 val)
    433  1.3.6.2  skrll {
    434  1.3.6.2  skrll 	return (val >> 1) | (val << 15);
    435  1.3.6.2  skrll }
    436  1.3.6.2  skrll 
    437  1.3.6.2  skrll static __inline u8 Lo8(u16 val)
    438  1.3.6.2  skrll {
    439  1.3.6.2  skrll 	return val & 0xff;
    440  1.3.6.2  skrll }
    441  1.3.6.2  skrll 
    442  1.3.6.2  skrll static __inline u8 Hi8(u16 val)
    443  1.3.6.2  skrll {
    444  1.3.6.2  skrll 	return val >> 8;
    445  1.3.6.2  skrll }
    446  1.3.6.2  skrll 
    447  1.3.6.2  skrll static __inline u16 Lo16(u32 val)
    448  1.3.6.2  skrll {
    449  1.3.6.2  skrll 	return val & 0xffff;
    450  1.3.6.2  skrll }
    451  1.3.6.2  skrll 
    452  1.3.6.2  skrll static __inline u16 Hi16(u32 val)
    453  1.3.6.2  skrll {
    454  1.3.6.2  skrll 	return val >> 16;
    455  1.3.6.2  skrll }
    456  1.3.6.2  skrll 
    457  1.3.6.2  skrll static __inline u16 Mk16(u8 hi, u8 lo)
    458  1.3.6.2  skrll {
    459  1.3.6.2  skrll 	return lo | (((u16) hi) << 8);
    460  1.3.6.2  skrll }
    461  1.3.6.2  skrll 
    462  1.3.6.2  skrll static __inline u16 Mk16_le(const u16 *v)
    463  1.3.6.2  skrll {
    464  1.3.6.2  skrll 	return le16toh(*v);
    465  1.3.6.2  skrll }
    466  1.3.6.2  skrll 
    467  1.3.6.2  skrll static const u16 Sbox[256] = {
    468  1.3.6.2  skrll 	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
    469  1.3.6.2  skrll 	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
    470  1.3.6.2  skrll 	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
    471  1.3.6.2  skrll 	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
    472  1.3.6.2  skrll 	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
    473  1.3.6.2  skrll 	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
    474  1.3.6.2  skrll 	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
    475  1.3.6.2  skrll 	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
    476  1.3.6.2  skrll 	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
    477  1.3.6.2  skrll 	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
    478  1.3.6.2  skrll 	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
    479  1.3.6.2  skrll 	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
    480  1.3.6.2  skrll 	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
    481  1.3.6.2  skrll 	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
    482  1.3.6.2  skrll 	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
    483  1.3.6.2  skrll 	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
    484  1.3.6.2  skrll 	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
    485  1.3.6.2  skrll 	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
    486  1.3.6.2  skrll 	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
    487  1.3.6.2  skrll 	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
    488  1.3.6.2  skrll 	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
    489  1.3.6.2  skrll 	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
    490  1.3.6.2  skrll 	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
    491  1.3.6.2  skrll 	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
    492  1.3.6.2  skrll 	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
    493  1.3.6.2  skrll 	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
    494  1.3.6.2  skrll 	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
    495  1.3.6.2  skrll 	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
    496  1.3.6.2  skrll 	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
    497  1.3.6.2  skrll 	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
    498  1.3.6.2  skrll 	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
    499  1.3.6.2  skrll 	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
    500  1.3.6.2  skrll };
    501  1.3.6.2  skrll 
    502  1.3.6.2  skrll static __inline u16 _S_(u16 v)
    503  1.3.6.2  skrll {
    504  1.3.6.2  skrll 	u16 t = Sbox[Hi8(v)];
    505  1.3.6.2  skrll 	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
    506  1.3.6.2  skrll }
    507  1.3.6.2  skrll 
    508  1.3.6.2  skrll #define PHASE1_LOOP_COUNT 8
    509  1.3.6.2  skrll 
    510  1.3.6.2  skrll static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
    511  1.3.6.2  skrll {
    512  1.3.6.2  skrll 	int i, j;
    513  1.3.6.2  skrll 
    514  1.3.6.2  skrll 	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
    515  1.3.6.2  skrll 	TTAK[0] = Lo16(IV32);
    516  1.3.6.2  skrll 	TTAK[1] = Hi16(IV32);
    517  1.3.6.2  skrll 	TTAK[2] = Mk16(TA[1], TA[0]);
    518  1.3.6.2  skrll 	TTAK[3] = Mk16(TA[3], TA[2]);
    519  1.3.6.2  skrll 	TTAK[4] = Mk16(TA[5], TA[4]);
    520  1.3.6.2  skrll 
    521  1.3.6.2  skrll 	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
    522  1.3.6.2  skrll 		j = 2 * (i & 1);
    523  1.3.6.2  skrll 		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
    524  1.3.6.2  skrll 		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
    525  1.3.6.2  skrll 		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
    526  1.3.6.2  skrll 		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
    527  1.3.6.2  skrll 		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
    528  1.3.6.2  skrll 	}
    529  1.3.6.2  skrll }
    530  1.3.6.2  skrll 
    531  1.3.6.2  skrll #ifndef _BYTE_ORDER
    532  1.3.6.2  skrll #error "Don't know native byte order"
    533  1.3.6.2  skrll #endif
    534  1.3.6.2  skrll 
    535  1.3.6.2  skrll static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
    536  1.3.6.2  skrll 			       u16 IV16)
    537  1.3.6.2  skrll {
    538  1.3.6.2  skrll 	/* Make temporary area overlap WEP seed so that the final copy can be
    539  1.3.6.2  skrll 	 * avoided on little endian hosts. */
    540  1.3.6.2  skrll 	u16 *PPK = (u16 *) &WEPSeed[4];
    541  1.3.6.2  skrll 
    542  1.3.6.2  skrll 	/* Step 1 - make copy of TTAK and bring in TSC */
    543  1.3.6.2  skrll 	PPK[0] = TTAK[0];
    544  1.3.6.2  skrll 	PPK[1] = TTAK[1];
    545  1.3.6.2  skrll 	PPK[2] = TTAK[2];
    546  1.3.6.2  skrll 	PPK[3] = TTAK[3];
    547  1.3.6.2  skrll 	PPK[4] = TTAK[4];
    548  1.3.6.2  skrll 	PPK[5] = TTAK[4] + IV16;
    549  1.3.6.2  skrll 
    550  1.3.6.2  skrll 	/* Step 2 - 96-bit bijective mixing using S-box */
    551  1.3.6.2  skrll 	PPK[0] += _S_(PPK[5] ^ Mk16_le((const u16 *) &TK[0]));
    552  1.3.6.2  skrll 	PPK[1] += _S_(PPK[0] ^ Mk16_le((const u16 *) &TK[2]));
    553  1.3.6.2  skrll 	PPK[2] += _S_(PPK[1] ^ Mk16_le((const u16 *) &TK[4]));
    554  1.3.6.2  skrll 	PPK[3] += _S_(PPK[2] ^ Mk16_le((const u16 *) &TK[6]));
    555  1.3.6.2  skrll 	PPK[4] += _S_(PPK[3] ^ Mk16_le((const u16 *) &TK[8]));
    556  1.3.6.2  skrll 	PPK[5] += _S_(PPK[4] ^ Mk16_le((const u16 *) &TK[10]));
    557  1.3.6.2  skrll 
    558  1.3.6.2  skrll 	PPK[0] += RotR1(PPK[5] ^ Mk16_le((const u16 *) &TK[12]));
    559  1.3.6.2  skrll 	PPK[1] += RotR1(PPK[0] ^ Mk16_le((const u16 *) &TK[14]));
    560  1.3.6.2  skrll 	PPK[2] += RotR1(PPK[1]);
    561  1.3.6.2  skrll 	PPK[3] += RotR1(PPK[2]);
    562  1.3.6.2  skrll 	PPK[4] += RotR1(PPK[3]);
    563  1.3.6.2  skrll 	PPK[5] += RotR1(PPK[4]);
    564  1.3.6.2  skrll 
    565  1.3.6.2  skrll 	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
    566  1.3.6.2  skrll 	 * WEPSeed[0..2] is transmitted as WEP IV */
    567  1.3.6.2  skrll 	WEPSeed[0] = Hi8(IV16);
    568  1.3.6.2  skrll 	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
    569  1.3.6.2  skrll 	WEPSeed[2] = Lo8(IV16);
    570  1.3.6.2  skrll 	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((const u16 *) &TK[0])) >> 1);
    571  1.3.6.2  skrll 
    572  1.3.6.2  skrll #if _BYTE_ORDER == _BIG_ENDIAN
    573  1.3.6.2  skrll 	{
    574  1.3.6.2  skrll 		int i;
    575  1.3.6.2  skrll 		for (i = 0; i < 6; i++)
    576  1.3.6.2  skrll 			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
    577  1.3.6.2  skrll 	}
    578  1.3.6.2  skrll #endif
    579  1.3.6.2  skrll }
    580  1.3.6.2  skrll 
    581  1.3.6.2  skrll static void
    582  1.3.6.2  skrll wep_encrypt(u8 *key, struct mbuf *m0, u_int off, size_t data_len,
    583  1.3.6.2  skrll 	uint8_t icv[IEEE80211_WEP_CRCLEN])
    584  1.3.6.2  skrll {
    585  1.3.6.2  skrll 	u32 i, j, k, crc;
    586  1.3.6.2  skrll 	size_t buflen;
    587  1.3.6.2  skrll 	u8 S[256];
    588  1.3.6.2  skrll 	u8 *pos;
    589  1.3.6.2  skrll 	struct mbuf *m;
    590  1.3.6.2  skrll #define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
    591  1.3.6.2  skrll 
    592  1.3.6.2  skrll 	/* Setup RC4 state */
    593  1.3.6.2  skrll 	for (i = 0; i < 256; i++)
    594  1.3.6.2  skrll 		S[i] = i;
    595  1.3.6.2  skrll 	j = 0;
    596  1.3.6.2  skrll 	for (i = 0; i < 256; i++) {
    597  1.3.6.2  skrll 		j = (j + S[i] + key[i & 0x0f]) & 0xff;
    598  1.3.6.2  skrll 		S_SWAP(i, j);
    599  1.3.6.2  skrll 	}
    600  1.3.6.2  skrll 
    601  1.3.6.2  skrll 	/* Compute CRC32 over unencrypted data and apply RC4 to data */
    602  1.3.6.2  skrll 	crc = ~0;
    603  1.3.6.2  skrll 	i = j = 0;
    604  1.3.6.2  skrll 	m = m0;
    605  1.3.6.2  skrll 	pos = mtod(m, uint8_t *) + off;
    606  1.3.6.2  skrll 	buflen = m->m_len - off;
    607  1.3.6.2  skrll 	for (;;) {
    608  1.3.6.2  skrll 		if (buflen > data_len)
    609  1.3.6.2  skrll 			buflen = data_len;
    610  1.3.6.2  skrll 		data_len -= buflen;
    611  1.3.6.2  skrll 		for (k = 0; k < buflen; k++) {
    612  1.3.6.2  skrll 			crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
    613  1.3.6.2  skrll 			i = (i + 1) & 0xff;
    614  1.3.6.2  skrll 			j = (j + S[i]) & 0xff;
    615  1.3.6.2  skrll 			S_SWAP(i, j);
    616  1.3.6.2  skrll 			*pos++ ^= S[(S[i] + S[j]) & 0xff];
    617  1.3.6.2  skrll 		}
    618  1.3.6.2  skrll 		m = m->m_next;
    619  1.3.6.2  skrll 		if (m == NULL) {
    620  1.3.6.2  skrll 			IASSERT(data_len == 0,
    621  1.3.6.2  skrll 			    ("out of buffers with data_len %zu\n", data_len));
    622  1.3.6.2  skrll 			break;
    623  1.3.6.2  skrll 		}
    624  1.3.6.2  skrll 		pos = mtod(m, uint8_t *);
    625  1.3.6.2  skrll 		buflen = m->m_len;
    626  1.3.6.2  skrll 	}
    627  1.3.6.2  skrll 	crc = ~crc;
    628  1.3.6.2  skrll 
    629  1.3.6.2  skrll 	/* Append little-endian CRC32 and encrypt it to produce ICV */
    630  1.3.6.2  skrll 	icv[0] = crc;
    631  1.3.6.2  skrll 	icv[1] = crc >> 8;
    632  1.3.6.2  skrll 	icv[2] = crc >> 16;
    633  1.3.6.2  skrll 	icv[3] = crc >> 24;
    634  1.3.6.2  skrll 	for (k = 0; k < IEEE80211_WEP_CRCLEN; k++) {
    635  1.3.6.2  skrll 		i = (i + 1) & 0xff;
    636  1.3.6.2  skrll 		j = (j + S[i]) & 0xff;
    637  1.3.6.2  skrll 		S_SWAP(i, j);
    638  1.3.6.2  skrll 		icv[k] ^= S[(S[i] + S[j]) & 0xff];
    639  1.3.6.2  skrll 	}
    640  1.3.6.2  skrll }
    641  1.3.6.2  skrll 
    642  1.3.6.2  skrll static int
    643  1.3.6.2  skrll wep_decrypt(u8 *key, struct mbuf *m, u_int off, size_t data_len)
    644  1.3.6.2  skrll {
    645  1.3.6.2  skrll 	u32 i, j, k, crc;
    646  1.3.6.2  skrll 	u8 S[256];
    647  1.3.6.2  skrll 	u8 *pos, icv[4];
    648  1.3.6.2  skrll 	size_t buflen;
    649  1.3.6.2  skrll 
    650  1.3.6.2  skrll 	/* Setup RC4 state */
    651  1.3.6.2  skrll 	for (i = 0; i < 256; i++)
    652  1.3.6.2  skrll 		S[i] = i;
    653  1.3.6.2  skrll 	j = 0;
    654  1.3.6.2  skrll 	for (i = 0; i < 256; i++) {
    655  1.3.6.2  skrll 		j = (j + S[i] + key[i & 0x0f]) & 0xff;
    656  1.3.6.2  skrll 		S_SWAP(i, j);
    657  1.3.6.2  skrll 	}
    658  1.3.6.2  skrll 
    659  1.3.6.2  skrll 	/* Apply RC4 to data and compute CRC32 over decrypted data */
    660  1.3.6.2  skrll 	crc = ~0;
    661  1.3.6.2  skrll 	i = j = 0;
    662  1.3.6.2  skrll 	pos = mtod(m, uint8_t *) + off;
    663  1.3.6.2  skrll 	buflen = m->m_len - off;
    664  1.3.6.2  skrll 	for (;;) {
    665  1.3.6.2  skrll 		if (buflen > data_len)
    666  1.3.6.2  skrll 			buflen = data_len;
    667  1.3.6.2  skrll 		data_len -= buflen;
    668  1.3.6.2  skrll 		for (k = 0; k < buflen; k++) {
    669  1.3.6.2  skrll 			i = (i + 1) & 0xff;
    670  1.3.6.2  skrll 			j = (j + S[i]) & 0xff;
    671  1.3.6.2  skrll 			S_SWAP(i, j);
    672  1.3.6.2  skrll 			*pos ^= S[(S[i] + S[j]) & 0xff];
    673  1.3.6.2  skrll 			crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8);
    674  1.3.6.2  skrll 			pos++;
    675  1.3.6.2  skrll 		}
    676  1.3.6.2  skrll 		m = m->m_next;
    677  1.3.6.2  skrll 		if (m == NULL) {
    678  1.3.6.2  skrll 			IASSERT(data_len == 0,
    679  1.3.6.2  skrll 			    ("out of buffers with data_len %zu\n", data_len));
    680  1.3.6.2  skrll 			break;
    681  1.3.6.2  skrll 		}
    682  1.3.6.2  skrll 		pos = mtod(m, uint8_t *);
    683  1.3.6.2  skrll 		buflen = m->m_len;
    684  1.3.6.2  skrll 	}
    685  1.3.6.2  skrll 	crc = ~crc;
    686  1.3.6.2  skrll 
    687  1.3.6.2  skrll 	/* Encrypt little-endian CRC32 and verify that it matches with the
    688  1.3.6.2  skrll 	 * received ICV */
    689  1.3.6.2  skrll 	icv[0] = crc;
    690  1.3.6.2  skrll 	icv[1] = crc >> 8;
    691  1.3.6.2  skrll 	icv[2] = crc >> 16;
    692  1.3.6.2  skrll 	icv[3] = crc >> 24;
    693  1.3.6.2  skrll 	for (k = 0; k < 4; k++) {
    694  1.3.6.2  skrll 		i = (i + 1) & 0xff;
    695  1.3.6.2  skrll 		j = (j + S[i]) & 0xff;
    696  1.3.6.2  skrll 		S_SWAP(i, j);
    697  1.3.6.2  skrll 		if ((icv[k] ^ S[(S[i] + S[j]) & 0xff]) != *pos++) {
    698  1.3.6.2  skrll 			/* ICV mismatch - drop frame */
    699  1.3.6.2  skrll 			return -1;
    700  1.3.6.2  skrll 		}
    701  1.3.6.2  skrll 	}
    702  1.3.6.2  skrll 
    703  1.3.6.2  skrll 	return 0;
    704  1.3.6.2  skrll }
    705  1.3.6.2  skrll 
    706  1.3.6.2  skrll 
    707  1.3.6.2  skrll static __inline u32 rotl(u32 val, int bits)
    708  1.3.6.2  skrll {
    709  1.3.6.2  skrll 	return (val << bits) | (val >> (32 - bits));
    710  1.3.6.2  skrll }
    711  1.3.6.2  skrll 
    712  1.3.6.2  skrll 
    713  1.3.6.2  skrll static __inline u32 rotr(u32 val, int bits)
    714  1.3.6.2  skrll {
    715  1.3.6.2  skrll 	return (val >> bits) | (val << (32 - bits));
    716  1.3.6.2  skrll }
    717  1.3.6.2  skrll 
    718  1.3.6.2  skrll 
    719  1.3.6.2  skrll static __inline u32 xswap(u32 val)
    720  1.3.6.2  skrll {
    721  1.3.6.2  skrll 	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
    722  1.3.6.2  skrll }
    723  1.3.6.2  skrll 
    724  1.3.6.2  skrll 
    725  1.3.6.2  skrll #define michael_block(l, r)	\
    726  1.3.6.2  skrll do {				\
    727  1.3.6.2  skrll 	r ^= rotl(l, 17);	\
    728  1.3.6.2  skrll 	l += r;			\
    729  1.3.6.2  skrll 	r ^= xswap(l);		\
    730  1.3.6.2  skrll 	l += r;			\
    731  1.3.6.2  skrll 	r ^= rotl(l, 3);	\
    732  1.3.6.2  skrll 	l += r;			\
    733  1.3.6.2  skrll 	r ^= rotr(l, 2);	\
    734  1.3.6.2  skrll 	l += r;			\
    735  1.3.6.2  skrll } while (0)
    736  1.3.6.2  skrll 
    737  1.3.6.2  skrll 
    738  1.3.6.2  skrll static __inline u32 get_le32_split(u8 b0, u8 b1, u8 b2, u8 b3)
    739  1.3.6.2  skrll {
    740  1.3.6.2  skrll 	return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
    741  1.3.6.2  skrll }
    742  1.3.6.2  skrll 
    743  1.3.6.2  skrll static __inline u32 get_le32(const u8 *p)
    744  1.3.6.2  skrll {
    745  1.3.6.2  skrll 	return get_le32_split(p[0], p[1], p[2], p[3]);
    746  1.3.6.2  skrll }
    747  1.3.6.2  skrll 
    748  1.3.6.2  skrll 
    749  1.3.6.2  skrll static __inline void put_le32(u8 *p, u32 v)
    750  1.3.6.2  skrll {
    751  1.3.6.2  skrll 	p[0] = v;
    752  1.3.6.2  skrll 	p[1] = v >> 8;
    753  1.3.6.2  skrll 	p[2] = v >> 16;
    754  1.3.6.2  skrll 	p[3] = v >> 24;
    755  1.3.6.2  skrll }
    756  1.3.6.2  skrll 
    757  1.3.6.2  skrll /*
    758  1.3.6.2  skrll  * Craft pseudo header used to calculate the MIC.
    759  1.3.6.2  skrll  */
    760  1.3.6.2  skrll static void
    761  1.3.6.2  skrll michael_mic_hdr(const struct ieee80211_frame *wh0, uint8_t hdr[16])
    762  1.3.6.2  skrll {
    763  1.3.6.2  skrll 	const struct ieee80211_frame_addr4 *wh =
    764  1.3.6.2  skrll 		(const struct ieee80211_frame_addr4 *) wh0;
    765  1.3.6.2  skrll 
    766  1.3.6.2  skrll 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
    767  1.3.6.2  skrll 	case IEEE80211_FC1_DIR_NODS:
    768  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
    769  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
    770  1.3.6.2  skrll 		break;
    771  1.3.6.2  skrll 	case IEEE80211_FC1_DIR_TODS:
    772  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
    773  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr2);
    774  1.3.6.2  skrll 		break;
    775  1.3.6.2  skrll 	case IEEE80211_FC1_DIR_FROMDS:
    776  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr, wh->i_addr1); /* DA */
    777  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr3);
    778  1.3.6.2  skrll 		break;
    779  1.3.6.2  skrll 	case IEEE80211_FC1_DIR_DSTODS:
    780  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr, wh->i_addr3); /* DA */
    781  1.3.6.2  skrll 		IEEE80211_ADDR_COPY(hdr + IEEE80211_ADDR_LEN, wh->i_addr4);
    782  1.3.6.2  skrll 		break;
    783  1.3.6.2  skrll 	}
    784  1.3.6.2  skrll 
    785  1.3.6.2  skrll 	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
    786  1.3.6.2  skrll 		const struct ieee80211_qosframe *qwh =
    787  1.3.6.2  skrll 			(const struct ieee80211_qosframe *) wh;
    788  1.3.6.2  skrll 		hdr[12] = qwh->i_qos[0] & IEEE80211_QOS_TID;
    789  1.3.6.2  skrll 	} else
    790  1.3.6.2  skrll 		hdr[12] = 0;
    791  1.3.6.2  skrll 	hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
    792  1.3.6.2  skrll }
    793  1.3.6.2  skrll 
    794  1.3.6.2  skrll static void
    795  1.3.6.2  skrll michael_mic(struct tkip_ctx *ctx, const u8 *key,
    796  1.3.6.2  skrll 	struct mbuf *m, u_int off, size_t data_len,
    797  1.3.6.2  skrll 	u8 mic[IEEE80211_WEP_MICLEN])
    798  1.3.6.2  skrll {
    799  1.3.6.2  skrll 	uint8_t hdr[16];
    800  1.3.6.2  skrll 	u32 l, r;
    801  1.3.6.2  skrll 	const uint8_t *data;
    802  1.3.6.2  skrll 	u_int space;
    803  1.3.6.2  skrll 
    804  1.3.6.2  skrll 	michael_mic_hdr(mtod(m, struct ieee80211_frame *), hdr);
    805  1.3.6.2  skrll 
    806  1.3.6.2  skrll 	l = get_le32(key);
    807  1.3.6.2  skrll 	r = get_le32(key + 4);
    808  1.3.6.2  skrll 
    809  1.3.6.2  skrll 	/* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
    810  1.3.6.2  skrll 	l ^= get_le32(hdr);
    811  1.3.6.2  skrll 	michael_block(l, r);
    812  1.3.6.2  skrll 	l ^= get_le32(&hdr[4]);
    813  1.3.6.2  skrll 	michael_block(l, r);
    814  1.3.6.2  skrll 	l ^= get_le32(&hdr[8]);
    815  1.3.6.2  skrll 	michael_block(l, r);
    816  1.3.6.2  skrll 	l ^= get_le32(&hdr[12]);
    817  1.3.6.2  skrll 	michael_block(l, r);
    818  1.3.6.2  skrll 
    819  1.3.6.2  skrll 	/* first buffer has special handling */
    820  1.3.6.2  skrll 	data = mtod(m, const uint8_t *) + off;
    821  1.3.6.2  skrll 	space = m->m_len - off;
    822  1.3.6.2  skrll 	for (;;) {
    823  1.3.6.2  skrll 		if (space > data_len)
    824  1.3.6.2  skrll 			space = data_len;
    825  1.3.6.2  skrll 		/* collect 32-bit blocks from current buffer */
    826  1.3.6.2  skrll 		while (space >= sizeof(uint32_t)) {
    827  1.3.6.2  skrll 			l ^= get_le32(data);
    828  1.3.6.2  skrll 			michael_block(l, r);
    829  1.3.6.2  skrll 			data += sizeof(uint32_t), space -= sizeof(uint32_t);
    830  1.3.6.2  skrll 			data_len -= sizeof(uint32_t);
    831  1.3.6.2  skrll 		}
    832  1.3.6.2  skrll 		if (data_len < sizeof(uint32_t))
    833  1.3.6.2  skrll 			break;
    834  1.3.6.2  skrll 		m = m->m_next;
    835  1.3.6.2  skrll 		if (m == NULL) {
    836  1.3.6.2  skrll 			IASSERT(0, ("out of data, data_len %zu\n", data_len));
    837  1.3.6.2  skrll 			break;
    838  1.3.6.2  skrll 		}
    839  1.3.6.2  skrll 		if (space != 0) {
    840  1.3.6.2  skrll 			const uint8_t *data_next;
    841  1.3.6.2  skrll 			/*
    842  1.3.6.2  skrll 			 * Block straddles buffers, split references.
    843  1.3.6.2  skrll 			 */
    844  1.3.6.2  skrll 			data_next = mtod(m, const uint8_t *);
    845  1.3.6.2  skrll 			IASSERT(m->m_len >= sizeof(uint32_t) - space,
    846  1.3.6.2  skrll 				("not enough data in following buffer, "
    847  1.3.6.2  skrll 				"m_len %u need %zu\n", m->m_len,
    848  1.3.6.2  skrll 				sizeof(uint32_t) - space));
    849  1.3.6.2  skrll 			switch (space) {
    850  1.3.6.2  skrll 			case 1:
    851  1.3.6.2  skrll 				l ^= get_le32_split(data[0], data_next[0],
    852  1.3.6.2  skrll 					data_next[1], data_next[2]);
    853  1.3.6.2  skrll 				data = data_next + 3;
    854  1.3.6.2  skrll 				space = m->m_len - 3;
    855  1.3.6.2  skrll 				break;
    856  1.3.6.2  skrll 			case 2:
    857  1.3.6.2  skrll 				l ^= get_le32_split(data[0], data[1],
    858  1.3.6.2  skrll 					data_next[0], data_next[1]);
    859  1.3.6.2  skrll 				data = data_next + 2;
    860  1.3.6.2  skrll 				space = m->m_len - 2;
    861  1.3.6.2  skrll 				break;
    862  1.3.6.2  skrll 			case 3:
    863  1.3.6.2  skrll 				l ^= get_le32_split(data[0], data[1],
    864  1.3.6.2  skrll 					data[2], data_next[0]);
    865  1.3.6.2  skrll 				data = data_next + 1;
    866  1.3.6.2  skrll 				space = m->m_len - 1;
    867  1.3.6.2  skrll 				break;
    868  1.3.6.2  skrll 			}
    869  1.3.6.2  skrll 			michael_block(l, r);
    870  1.3.6.2  skrll 			data_len -= sizeof(uint32_t);
    871  1.3.6.2  skrll 		} else {
    872  1.3.6.2  skrll 			/*
    873  1.3.6.2  skrll 			 * Setup for next buffer.
    874  1.3.6.2  skrll 			 */
    875  1.3.6.2  skrll 			data = mtod(m, const uint8_t *);
    876  1.3.6.2  skrll 			space = m->m_len;
    877  1.3.6.2  skrll 		}
    878  1.3.6.2  skrll 	}
    879  1.3.6.2  skrll 	/* Last block and padding (0x5a, 4..7 x 0) */
    880  1.3.6.2  skrll 	switch (data_len) {
    881  1.3.6.2  skrll 	case 0:
    882  1.3.6.2  skrll 		l ^= get_le32_split(0x5a, 0, 0, 0);
    883  1.3.6.2  skrll 		break;
    884  1.3.6.2  skrll 	case 1:
    885  1.3.6.2  skrll 		l ^= get_le32_split(data[0], 0x5a, 0, 0);
    886  1.3.6.2  skrll 		break;
    887  1.3.6.2  skrll 	case 2:
    888  1.3.6.2  skrll 		l ^= get_le32_split(data[0], data[1], 0x5a, 0);
    889  1.3.6.2  skrll 		break;
    890  1.3.6.2  skrll 	case 3:
    891  1.3.6.2  skrll 		l ^= get_le32_split(data[0], data[1], data[2], 0x5a);
    892  1.3.6.2  skrll 		break;
    893  1.3.6.2  skrll 	}
    894  1.3.6.2  skrll 	michael_block(l, r);
    895  1.3.6.2  skrll 	/* l ^= 0; */
    896  1.3.6.2  skrll 	michael_block(l, r);
    897  1.3.6.2  skrll 
    898  1.3.6.2  skrll 	put_le32(mic, l);
    899  1.3.6.2  skrll 	put_le32(mic + 4, r);
    900  1.3.6.2  skrll }
    901  1.3.6.2  skrll 
    902  1.3.6.2  skrll static int
    903  1.3.6.2  skrll tkip_encrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
    904  1.3.6.2  skrll 	struct mbuf *m, int hdrlen)
    905  1.3.6.2  skrll {
    906  1.3.6.2  skrll 	struct ieee80211_frame *wh;
    907  1.3.6.2  skrll 	uint8_t icv[IEEE80211_WEP_CRCLEN];
    908  1.3.6.2  skrll 
    909  1.3.6.2  skrll 	ctx->tc_ic->ic_stats.is_crypto_tkip++;
    910  1.3.6.2  skrll 
    911  1.3.6.2  skrll 	wh = mtod(m, struct ieee80211_frame *);
    912  1.3.6.2  skrll 	if (!ctx->tx_phase1_done) {
    913  1.3.6.2  skrll 		tkip_mixing_phase1(ctx->tx_ttak, key->wk_key, wh->i_addr2,
    914  1.3.6.2  skrll 				   (u32)(key->wk_keytsc >> 16));
    915  1.3.6.2  skrll 		ctx->tx_phase1_done = 1;
    916  1.3.6.2  skrll 	}
    917  1.3.6.2  skrll 	tkip_mixing_phase2(ctx->tx_rc4key, key->wk_key, ctx->tx_ttak,
    918  1.3.6.2  skrll 		(u16) key->wk_keytsc);
    919  1.3.6.2  skrll 
    920  1.3.6.2  skrll 	wep_encrypt(ctx->tx_rc4key,
    921  1.3.6.2  skrll 		m, hdrlen + tkip.ic_header,
    922  1.3.6.2  skrll 		m->m_pkthdr.len - (hdrlen + tkip.ic_header),
    923  1.3.6.2  skrll 		icv);
    924  1.3.6.2  skrll 	(void) m_append(m, IEEE80211_WEP_CRCLEN, icv);	/* XXX check return */
    925  1.3.6.2  skrll 
    926  1.3.6.2  skrll 	key->wk_keytsc++;
    927  1.3.6.2  skrll 	if ((u16)(key->wk_keytsc) == 0)
    928  1.3.6.2  skrll 		ctx->tx_phase1_done = 0;
    929  1.3.6.2  skrll 	return 1;
    930  1.3.6.2  skrll }
    931  1.3.6.2  skrll 
    932  1.3.6.2  skrll static int
    933  1.3.6.2  skrll tkip_decrypt(struct tkip_ctx *ctx, struct ieee80211_key *key,
    934  1.3.6.2  skrll 	struct mbuf *m, int hdrlen)
    935  1.3.6.2  skrll {
    936  1.3.6.2  skrll 	struct ieee80211_frame *wh;
    937  1.3.6.2  skrll 	u32 iv32;
    938  1.3.6.2  skrll 	u16 iv16;
    939  1.3.6.2  skrll 
    940  1.3.6.2  skrll 	ctx->tc_ic->ic_stats.is_crypto_tkip++;
    941  1.3.6.2  skrll 
    942  1.3.6.2  skrll 	wh = mtod(m, struct ieee80211_frame *);
    943  1.3.6.2  skrll 	/* NB: tkip_decap already verified header and left seq in rx_rsc */
    944  1.3.6.2  skrll 	iv16 = (u16) ctx->rx_rsc;
    945  1.3.6.2  skrll 	iv32 = (u32) (ctx->rx_rsc >> 16);
    946  1.3.6.2  skrll 
    947  1.3.6.2  skrll 	if (iv32 != (u32)(key->wk_keyrsc >> 16) || !ctx->rx_phase1_done) {
    948  1.3.6.2  skrll 		tkip_mixing_phase1(ctx->rx_ttak, key->wk_key,
    949  1.3.6.2  skrll 			wh->i_addr2, iv32);
    950  1.3.6.2  skrll 		ctx->rx_phase1_done = 1;
    951  1.3.6.2  skrll 	}
    952  1.3.6.2  skrll 	tkip_mixing_phase2(ctx->rx_rc4key, key->wk_key, ctx->rx_ttak, iv16);
    953  1.3.6.2  skrll 
    954  1.3.6.2  skrll 	/* NB: m is unstripped; deduct headers + ICV to get payload */
    955  1.3.6.2  skrll 	if (wep_decrypt(ctx->rx_rc4key,
    956  1.3.6.2  skrll 		m, hdrlen + tkip.ic_header,
    957  1.3.6.2  skrll 	        m->m_pkthdr.len - (hdrlen + tkip.ic_header + tkip.ic_trailer))) {
    958  1.3.6.2  skrll 		if (iv32 != (u32)(key->wk_keyrsc >> 16)) {
    959  1.3.6.2  skrll 			/* Previously cached Phase1 result was already lost, so
    960  1.3.6.2  skrll 			 * it needs to be recalculated for the next packet. */
    961  1.3.6.2  skrll 			ctx->rx_phase1_done = 0;
    962  1.3.6.2  skrll 		}
    963  1.3.6.2  skrll 		IEEE80211_DPRINTF(ctx->tc_ic, IEEE80211_MSG_CRYPTO,
    964  1.3.6.2  skrll 		    "[%s] TKIP ICV mismatch on decrypt\n",
    965  1.3.6.2  skrll 		    ether_sprintf(wh->i_addr2));
    966  1.3.6.2  skrll 		ctx->tc_ic->ic_stats.is_rx_tkipicv++;
    967  1.3.6.2  skrll 		return 0;
    968  1.3.6.2  skrll 	}
    969  1.3.6.2  skrll 	return 1;
    970  1.3.6.2  skrll }
    971