source: bootcd/isolinux/syslinux-6.03/gpxe/src/net/80211/wpa_tkip.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 16.2 KB
Line 
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};
Note: See TracBrowser for help on using the repository browser.