1/*
2 * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19FILE_LICENCE ( GPL2_OR_LATER );
20
21#include <gpxe/net80211.h>
22#include <gpxe/crypto.h>
23#include <gpxe/hmac.h>
24#include <gpxe/sha1.h>
25#include <gpxe/md5.h>
26#include <gpxe/crc32.h>
27#include <gpxe/arc4.h>
28#include <gpxe/wpa.h>
29#include <byteswap.h>
30#include <errno.h>
31
32/** @file
33 *
34 * Backend for WPA using the TKIP encryption standard.
35 */
36
37/** Context for one direction of TKIP, either encryption or decryption */
38struct tkip_dir_ctx
39{
40	/** High 32 bits of last sequence counter value used */
41	u32 tsc_hi;
42
43	/** Low 32 bits of last sequence counter value used */
44	u16 tsc_lo;
45
46	/** MAC address used to derive TTAK */
47	u8 mac[ETH_ALEN];
48
49	/** If TRUE, TTAK is valid */
50	u16 ttak_ok;
51
52	/** TKIP-mixed transmit address and key, depends on tsc_hi and MAC */
53	u16 ttak[5];
54};
55
56/** Context for TKIP encryption and decryption */
57struct tkip_ctx
58{
59	/** Temporal key to use */
60	struct tkip_tk tk;
61
62	/** State for encryption */
63	struct tkip_dir_ctx enc;
64
65	/** State for decryption */
66	struct tkip_dir_ctx dec;
67};
68
69/** Header structure at the beginning of TKIP frame data */
70struct tkip_head
71{
72	u8 tsc1;		/**< High byte of low 16 bits of TSC */
73	u8 seed1;		/**< Second byte of WEP seed */
74	u8 tsc0;		/**< Low byte of TSC */
75	u8 kid;			/**< Key ID and ExtIV byte */
76	u32 tsc_hi;		/**< High 32 bits of TSC, as an ExtIV */
77} __attribute__ (( packed ));
78
79
80/** TKIP header overhead (IV + KID + ExtIV) */
81#define TKIP_HEAD_LEN	8
82
83/** TKIP trailer overhead (MIC + ICV) [assumes unfragmented] */
84#define TKIP_FOOT_LEN	12
85
86/** TKIP MIC length */
87#define TKIP_MIC_LEN	8
88
89/** TKIP ICV length */
90#define TKIP_ICV_LEN	4
91
92
93/** TKIP S-box */
94static const u16 Sbox[256] = {
95	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
96	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
97	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
98	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
99	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
100	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
101	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
102	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
103	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
104	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
105	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
106	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
107	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
108	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
109	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
110	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
111	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
112	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
113	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
114	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
115	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
116	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
117	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
118	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
119	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
120	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
121	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
122	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
123	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
124	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
125	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
126	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
127};
128
129/**
130 * Perform S-box mapping on a 16-bit value
131 *
132 * @v v		Value to perform S-box mapping on
133 * @ret Sv	S-box mapped value
134 */
135static inline u16 S ( u16 v )
136{
137	return Sbox[v & 0xFF] ^ swap16 ( Sbox[v >> 8] );
138}
139
140/**
141 * Rotate 16-bit value right
142 *
143 * @v v		Value to rotate
144 * @v bits	Number of bits to rotate by
145 * @ret rotv	Rotated value
146 */
147static inline u16 ror16 ( u16 v, int bits )
148{
149	return ( v >> bits ) | ( v << ( 16 - bits ) );
150}
151
152/**
153 * Rotate 32-bit value right
154 *
155 * @v v		Value to rotate
156 * @v bits	Number of bits to rotate by
157 * @ret rotv	Rotated value
158 */
159static inline u32 ror32 ( u32 v, int bits )
160{
161	return ( v >> bits ) | ( v << ( 32 - bits ) );
162}
163
164/**
165 * Rotate 32-bit value left
166 *
167 * @v v		Value to rotate
168 * @v bits	Number of bits to rotate by
169 * @ret rotv	Rotated value
170 */
171static inline u32 rol32 ( u32 v, int bits )
172{
173	return ( v << bits ) | ( v >> ( 32 - bits ) );
174}
175
176
177/**
178 * Initialise TKIP state and install key
179 *
180 * @v crypto	TKIP cryptosystem structure
181 * @v key	Pointer to tkip_tk to install
182 * @v keylen	Length of key (32 bytes)
183 * @v rsc	Initial receive sequence counter
184 */
185static int tkip_init ( struct net80211_crypto *crypto, const void *key,
186		       int keylen, const void *rsc )
187{
188	struct tkip_ctx *ctx = crypto->priv;
189	const u8 *rscb = rsc;
190
191	if ( keylen != sizeof ( ctx->tk ) )
192		return -EINVAL;
193
194	if ( rscb ) {
195		ctx->dec.tsc_lo =   ( rscb[1] <<  8 ) |   rscb[0];
196		ctx->dec.tsc_hi = ( ( rscb[5] << 24 ) | ( rscb[4] << 16 ) |
197				    ( rscb[3] <<  8 ) |   rscb[2] );
198	}
199
200	memcpy ( &ctx->tk, key, sizeof ( ctx->tk ) );
201
202	return 0;
203}
204
205/**
206 * Perform TKIP key mixing, phase 1
207 *
208 * @v dctx	TKIP directional context
209 * @v tk	TKIP temporal key
210 * @v mac	MAC address of transmitter
211 *
212 * This recomputes the TTAK in @a dctx if necessary, and sets
213 * @c dctx->ttak_ok.
214 */
215static void tkip_mix_1 ( struct tkip_dir_ctx *dctx, struct tkip_tk *tk, u8 *mac )
216{
217	int i, j;
218
219	if ( dctx->ttak_ok && ! memcmp ( mac, dctx->mac, ETH_ALEN ) )
220		return;
221
222	memcpy ( dctx->mac, mac, ETH_ALEN );
223
224	dctx->ttak[0] = dctx->tsc_hi & 0xFFFF;
225	dctx->ttak[1] = dctx->tsc_hi >> 16;
226	dctx->ttak[2] = ( mac[1] << 8 ) | mac[0];
227	dctx->ttak[3] = ( mac[3] << 8 ) | mac[2];
228	dctx->ttak[4] = ( mac[5] << 8 ) | mac[4];
229
230	for ( i = 0; i < 8; i++ ) {
231		j = 2 * ( i & 1 );
232
233		dctx->ttak[0] += S ( dctx->ttak[4] ^ ( ( tk->key[1 + j] << 8 ) |
234						         tk->key[0 + j] ) );
235		dctx->ttak[1] += S ( dctx->ttak[0] ^ ( ( tk->key[5 + j] << 8 ) |
236						         tk->key[4 + j] ) );
237		dctx->ttak[2] += S ( dctx->ttak[1] ^ ( ( tk->key[9 + j] << 8 ) |
238						         tk->key[8 + j] ) );
239		dctx->ttak[3] += S ( dctx->ttak[2] ^ ( ( tk->key[13+ j] << 8 ) |
240						         tk->key[12+ j] ) );
241		dctx->ttak[4] += S ( dctx->ttak[3] ^ ( ( tk->key[1 + j] << 8 ) |
242						         tk->key[0 + j] ) ) + i;
243	}
244
245	dctx->ttak_ok = 1;
246}
247
248/**
249 * Perform TKIP key mixing, phase 2
250 *
251 * @v dctx	TKIP directional context
252 * @v tk	TKIP temporal key
253 * @ret key	ARC4 key, 16 bytes long
254 */
255static void tkip_mix_2 ( struct tkip_dir_ctx *dctx, struct tkip_tk *tk,
256			 void *key )
257{
258	u8 *kb = key;
259	u16 ppk[6];
260	int i;
261
262	memcpy ( ppk, dctx->ttak, sizeof ( dctx->ttak ) );
263	ppk[5] = dctx->ttak[4] + dctx->tsc_lo;
264
265	ppk[0] += S ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) );
266	ppk[1] += S ( ppk[0] ^ ( ( tk->key[3] << 8 ) | tk->key[2] ) );
267	ppk[2] += S ( ppk[1] ^ ( ( tk->key[5] << 8 ) | tk->key[4] ) );
268	ppk[3] += S ( ppk[2] ^ ( ( tk->key[7] << 8 ) | tk->key[6] ) );
269	ppk[4] += S ( ppk[3] ^ ( ( tk->key[9] << 8 ) | tk->key[8] ) );
270	ppk[5] += S ( ppk[4] ^ ( ( tk->key[11] << 8 ) | tk->key[10] ) );
271
272	ppk[0] += ror16 ( ppk[5] ^ ( ( tk->key[13] << 8 ) | tk->key[12] ), 1 );
273	ppk[1] += ror16 ( ppk[0] ^ ( ( tk->key[15] << 8 ) | tk->key[14] ), 1 );
274	ppk[2] += ror16 ( ppk[1], 1 );
275	ppk[3] += ror16 ( ppk[2], 1 );
276	ppk[4] += ror16 ( ppk[3], 1 );
277	ppk[5] += ror16 ( ppk[4], 1 );
278
279	kb[0] = dctx->tsc_lo >> 8;
280	kb[1] = ( ( dctx->tsc_lo >> 8 ) | 0x20 ) & 0x7F;
281	kb[2] = dctx->tsc_lo & 0xFF;
282	kb[3] = ( ( ppk[5] ^ ( ( tk->key[1] << 8 ) | tk->key[0] ) ) >> 1 )
283		& 0xFF;
284
285	for ( i = 0; i < 6; i++ ) {
286		kb[4 + 2*i] = ppk[i] & 0xFF;
287		kb[5 + 2*i] = ppk[i] >> 8;
288	}
289}
290
291/**
292 * Update Michael message integrity code based on next 32-bit word of data
293 *
294 * @v V		Michael code state (two 32-bit words)
295 * @v word	Next 32-bit word of data
296 */
297static void tkip_feed_michael ( u32 *V, u32 word )
298{
299	V[0] ^= word;
300	V[1] ^= rol32 ( V[0], 17 );
301	V[0] += V[1];
302	V[1] ^= ( ( V[0] & 0xFF00FF00 ) >> 8 ) | ( ( V[0] & 0x00FF00FF ) << 8 );
303	V[0] += V[1];
304	V[1] ^= rol32 ( V[0], 3 );
305	V[0] += V[1];
306	V[1] ^= ror32 ( V[0], 2 );
307	V[0] += V[1];
308}
309
310/**
311 * Calculate Michael message integrity code
312 *
313 * @v key	MIC key to use (8 bytes)
314 * @v da	Destination link-layer address
315 * @v sa	Source link-layer address
316 * @v data	Start of data to calculate over
317 * @v len	Length of header + data
318 * @ret mic	Calculated Michael MIC (8 bytes)
319 */
320static void tkip_michael ( const void *key, const void *da, const void *sa,
321			   const void *data, size_t len, void *mic )
322{
323	u32 V[2];		/* V[0] = "l", V[1] = "r" in 802.11 */
324	union {
325		u8 byte[12];
326		u32 word[3];
327	} cap;
328	const u8 *ptr = data;
329	const u8 *end = ptr + len;
330	int i;
331
332	memcpy ( V, key, sizeof ( V ) );
333	V[0] = le32_to_cpu ( V[0] );
334	V[1] = le32_to_cpu ( V[1] );
335
336	/* Feed in header (we assume non-QoS, so Priority = 0) */
337	memcpy ( &cap.byte[0], da, ETH_ALEN );
338	memcpy ( &cap.byte[6], sa, ETH_ALEN );
339	tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
340	tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
341	tkip_feed_michael ( V, le32_to_cpu ( cap.word[2] ) );
342	tkip_feed_michael ( V, 0 );
343
344	/* Feed in data */
345	while ( ptr + 4 <= end ) {
346		tkip_feed_michael ( V, le32_to_cpu ( *( u32 * ) ptr ) );
347		ptr += 4;
348	}
349
350	/* Add unaligned part and padding */
351	for ( i = 0; ptr < end; i++ )
352		cap.byte[i] = *ptr++;
353	cap.byte[i++] = 0x5a;
354	for ( ; i < 8; i++ )
355		cap.byte[i] = 0;
356
357	/* Feed in padding */
358	tkip_feed_michael ( V, le32_to_cpu ( cap.word[0] ) );
359	tkip_feed_michael ( V, le32_to_cpu ( cap.word[1] ) );
360
361	/* Output MIC */
362	V[0] = cpu_to_le32 ( V[0] );
363	V[1] = cpu_to_le32 ( V[1] );
364	memcpy ( mic, V, sizeof ( V ) );
365}
366
367/**
368 * Encrypt a packet using TKIP
369 *
370 * @v crypto	TKIP cryptosystem
371 * @v iob	I/O buffer containing cleartext packet
372 * @ret eiob	I/O buffer containing encrypted packet
373 */
374static struct io_buffer * tkip_encrypt ( struct net80211_crypto *crypto,
375					 struct io_buffer *iob )
376{
377	struct tkip_ctx *ctx = crypto->priv;
378	struct ieee80211_frame *hdr = iob->data;
379	struct io_buffer *eiob;
380	struct arc4_ctx arc4;
381	u8 key[16];
382	struct tkip_head head;
383	u8 mic[8];
384	u32 icv;
385	const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
386	int datalen = iob_len ( iob ) - hdrlen;
387
388	ctx->enc.tsc_lo++;
389	if ( ctx->enc.tsc_lo == 0 ) {
390		ctx->enc.tsc_hi++;
391		ctx->enc.ttak_ok = 0;
392	}
393
394	tkip_mix_1 ( &ctx->enc, &ctx->tk, hdr->addr2 );
395	tkip_mix_2 ( &ctx->enc, &ctx->tk, key );
396
397	eiob = alloc_iob ( iob_len ( iob ) + TKIP_HEAD_LEN + TKIP_FOOT_LEN );
398	if ( ! eiob )
399		return NULL;
400
401	/* Copy frame header */
402	memcpy ( iob_put ( eiob, hdrlen ), iob->data, hdrlen );
403	hdr = eiob->data;
404	hdr->fc |= IEEE80211_FC_PROTECTED;
405
406	/* Fill in IV and key ID byte, and extended IV */
407	memcpy ( &head, key, 3 );
408	head.kid = 0x20;		/* have Extended IV, key ID 0 */
409	head.tsc_hi = cpu_to_le32 ( ctx->enc.tsc_hi );
410	memcpy ( iob_put ( eiob, sizeof ( head ) ), &head, sizeof ( head ) );
411
412	/* Copy and encrypt the data */
413	cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
414	cipher_encrypt ( &arc4_algorithm, &arc4, iob->data + hdrlen,
415			 iob_put ( eiob, datalen ), datalen );
416
417	/* Add MIC */
418	hdr = iob->data;
419	tkip_michael ( &ctx->tk.mic.tx, hdr->addr3, hdr->addr2,
420		       iob->data + hdrlen, datalen, mic );
421	cipher_encrypt ( &arc4_algorithm, &arc4, mic,
422			 iob_put ( eiob, sizeof ( mic ) ), sizeof ( mic ) );
423
424	/* Add ICV */
425	icv = crc32_le ( ~0, iob->data + hdrlen, datalen );
426	icv = crc32_le ( icv, mic, sizeof ( mic ) );
427	icv = cpu_to_le32 ( ~icv );
428	cipher_encrypt ( &arc4_algorithm, &arc4, &icv,
429			 iob_put ( eiob, TKIP_ICV_LEN ), TKIP_ICV_LEN );
430
431	DBGC2 ( ctx, "WPA-TKIP %p: encrypted packet %p -> %p\n", ctx,
432		iob, eiob );
433
434	return eiob;
435}
436
437/**
438 * Decrypt a packet using TKIP
439 *
440 * @v crypto	TKIP cryptosystem
441 * @v eiob	I/O buffer containing encrypted packet
442 * @ret iob	I/O buffer containing cleartext packet
443 */
444static struct io_buffer * tkip_decrypt ( struct net80211_crypto *crypto,
445					 struct io_buffer *eiob )
446{
447	struct tkip_ctx *ctx = crypto->priv;
448	struct ieee80211_frame *hdr;
449	struct io_buffer *iob;
450	const int hdrlen = IEEE80211_TYP_FRAME_HEADER_LEN;
451	int datalen = iob_len ( eiob ) - hdrlen - TKIP_HEAD_LEN - TKIP_FOOT_LEN;
452	struct tkip_head *head;
453	struct arc4_ctx arc4;
454	u16 rx_tsc_lo;
455	u8 key[16];
456	u8 mic[8];
457	u32 icv, crc;
458
459	iob = alloc_iob ( hdrlen + datalen + TKIP_FOOT_LEN );
460	if ( ! iob )
461		return NULL;
462
463	/* Copy frame header */
464	memcpy ( iob_put ( iob, hdrlen ), eiob->data, hdrlen );
465	hdr = iob->data;
466	hdr->fc &= ~IEEE80211_FC_PROTECTED;
467
468	/* Check and update TSC */
469	head = eiob->data + hdrlen;
470	rx_tsc_lo = ( head->tsc1 << 8 ) | head->tsc0;
471
472	if ( head->tsc_hi < ctx->dec.tsc_hi ||
473	     ( head->tsc_hi == ctx->dec.tsc_hi &&
474	       rx_tsc_lo <= ctx->dec.tsc_lo ) ) {
475		DBGC ( ctx, "WPA-TKIP %p: packet received out of order "
476		       "(%08x:%04x <= %08x:%04x)\n", ctx, head->tsc_hi,
477		       rx_tsc_lo, ctx->dec.tsc_hi, ctx->dec.tsc_lo );
478		free_iob ( iob );
479		return NULL;
480	}
481	ctx->dec.tsc_lo = rx_tsc_lo;
482	if ( ctx->dec.tsc_hi != head->tsc_hi ) {
483		ctx->dec.ttak_ok = 0;
484		ctx->dec.tsc_hi = head->tsc_hi;
485	}
486
487	/* Calculate key */
488	tkip_mix_1 ( &ctx->dec, &ctx->tk, hdr->addr2 );
489	tkip_mix_2 ( &ctx->dec, &ctx->tk, key );
490
491	/* Copy-decrypt data, MIC, ICV */
492	cipher_setkey ( &arc4_algorithm, &arc4, key, 16 );
493	cipher_decrypt ( &arc4_algorithm, &arc4,
494			 eiob->data + hdrlen + TKIP_HEAD_LEN,
495			 iob_put ( iob, datalen ), datalen + TKIP_FOOT_LEN );
496
497	/* Check ICV */
498	icv = le32_to_cpu ( *( u32 * ) ( iob->tail + TKIP_MIC_LEN ) );
499	crc = ~crc32_le ( ~0, iob->data + hdrlen, datalen + TKIP_MIC_LEN );
500	if ( crc != icv ) {
501		DBGC ( ctx, "WPA-TKIP %p CRC mismatch: expect %08x, get %08x\n",
502		       ctx, icv, crc );
503		free_iob ( iob );
504		return NULL;
505	}
506
507	/* Check MIC */
508	tkip_michael ( &ctx->tk.mic.rx, hdr->addr1, hdr->addr3,
509		       iob->data + hdrlen, datalen, mic );
510	if ( memcmp ( mic, iob->tail, TKIP_MIC_LEN ) != 0 ) {
511		DBGC ( ctx, "WPA-TKIP %p ALERT! MIC failure\n", ctx );
512		/* XXX we should do the countermeasures here */
513		free_iob ( iob );
514		return NULL;
515	}
516
517	DBGC2 ( ctx, "WPA-TKIP %p: decrypted packet %p -> %p\n", ctx,
518		eiob, iob );
519
520	return iob;
521}
522
523/** TKIP cryptosystem */
524struct net80211_crypto tkip_crypto __net80211_crypto = {
525	.algorithm = NET80211_CRYPT_TKIP,
526	.init = tkip_init,
527	.encrypt = tkip_encrypt,
528	.decrypt = tkip_decrypt,
529	.priv_len = sizeof ( struct tkip_ctx ),
530};
531
532
533
534
535/**
536 * Calculate HMAC-MD5 MIC for EAPOL-Key frame
537 *
538 * @v kck	Key Confirmation Key, 16 bytes
539 * @v msg	Message to calculate MIC over
540 * @v len	Number of bytes to calculate MIC over
541 * @ret mic	Calculated MIC, 16 bytes long
542 */
543static void tkip_kie_mic ( const void *kck, const void *msg, size_t len,
544			   void *mic )
545{
546	struct md5_ctx md5;
547	u8 kckb[16];
548	size_t kck_len = 16;
549
550	memcpy ( kckb, kck, kck_len );
551
552	hmac_init ( &md5_algorithm, &md5, kckb, &kck_len );
553	hmac_update ( &md5_algorithm, &md5, msg, len );
554	hmac_final ( &md5_algorithm, &md5, kckb, &kck_len, mic );
555}
556
557/**
558 * Decrypt key data in EAPOL-Key frame
559 *
560 * @v kek	Key Encryption Key, 16 bytes
561 * @v iv	Initialisation vector, 16 bytes
562 * @v msg	Message to decrypt
563 * @v len	Length of message
564 * @ret msg	Decrypted message in place of original
565 * @ret len	Unchanged
566 * @ret rc	Always 0 for success
567 */
568static int tkip_kie_decrypt ( const void *kek, const void *iv,
569			      void *msg, u16 *len )
570{
571	u8 key[32];
572	memcpy ( key, iv, 16 );
573	memcpy ( key + 16, kek, 16 );
574
575	arc4_skip ( key, 32, 256, msg, msg, *len );
576
577	return 0;
578}
579
580
581/** TKIP-style key integrity and encryption handler */
582struct wpa_kie tkip_kie __wpa_kie = {
583	.version = EAPOL_KEY_VERSION_WPA,
584	.mic = tkip_kie_mic,
585	.decrypt = tkip_kie_decrypt,
586};
587