~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to ubuntu/rtl8192se/rtllib/rtllib_crypt_tkip.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3
 
 *
4
 
 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License version 2 as
8
 
 * published by the Free Software Foundation. See README and COPYING for
9
 
 * more details.
10
 
 */
11
 
 
12
 
#include <linux/version.h>
13
 
#include <linux/module.h>
14
 
#include <linux/init.h>
15
 
#include <linux/slab.h>
16
 
#include <linux/random.h>
17
 
#include <linux/skbuff.h>
18
 
#include <linux/netdevice.h>
19
 
#include <linux/if_ether.h>
20
 
#include <linux/if_arp.h>
21
 
#include <asm/string.h>
22
 
#ifdef _RTL8192_EXT_PATCH_      
23
 
#include <linux/etherdevice.h>
24
 
#endif
25
 
#include "rtllib.h"
26
 
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
27
 
#endif
28
 
 
29
 
 
30
 
#if defined(BUILT_IN_CRYPTO) || (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
31
 
#include "rtl_crypto.h"
32
 
#else
33
 
#include <linux/crypto.h>
34
 
#endif
35
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 
36
 
    #include <asm/scatterlist.h>
37
 
#else
38
 
        #include <linux/scatterlist.h>
39
 
#endif
40
 
       
41
 
#include <linux/crc32.h>
42
 
 
43
 
#ifndef BUILT_IN_RTLLIB
44
 
MODULE_AUTHOR("Jouni Malinen");
45
 
MODULE_DESCRIPTION("Host AP crypt: TKIP");
46
 
MODULE_LICENSE("GPL");
47
 
#endif
48
 
 
49
 
 
50
 
struct rtllib_tkip_data {
51
 
#define TKIP_KEY_LEN 32
52
 
        u8 key[TKIP_KEY_LEN];
53
 
        int key_set;
54
 
 
55
 
        u32 tx_iv32;
56
 
        u16 tx_iv16;
57
 
        u16 tx_ttak[5];
58
 
        int tx_phase1_done;
59
 
 
60
 
        u32 rx_iv32;
61
 
        u16 rx_iv16;
62
 
      bool initialized;
63
 
        u16 rx_ttak[5];
64
 
        int rx_phase1_done;
65
 
        u32 rx_iv32_new;
66
 
        u16 rx_iv16_new;
67
 
 
68
 
        u32 dot11RSNAStatsTKIPReplays;
69
 
        u32 dot11RSNAStatsTKIPICVErrors;
70
 
        u32 dot11RSNAStatsTKIPLocalMICFailures;
71
 
 
72
 
        int key_idx;
73
 
#if  ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
74
 
        struct crypto_blkcipher *rx_tfm_arc4;
75
 
        struct crypto_hash *rx_tfm_michael;
76
 
        struct crypto_blkcipher *tx_tfm_arc4;
77
 
        struct crypto_hash *tx_tfm_michael;
78
 
#else
79
 
        struct crypto_tfm *tx_tfm_arc4;
80
 
        struct crypto_tfm *tx_tfm_michael;
81
 
        struct crypto_tfm *rx_tfm_arc4;
82
 
        struct crypto_tfm *rx_tfm_michael;
83
 
#endif
84
 
        /* scratch buffers for virt_to_page() (crypto API) */
85
 
        u8 rx_hdr[16], tx_hdr[16];
86
 
};
87
 
 
88
 
static void * rtllib_tkip_init(int key_idx)
89
 
{
90
 
        struct rtllib_tkip_data *priv;
91
 
 
92
 
        priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
93
 
        if (priv == NULL)
94
 
                goto fail;
95
 
        memset(priv, 0, sizeof(*priv));
96
 
        priv->key_idx = key_idx;
97
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
98
 
        priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
99
 
        if (priv->tx_tfm_arc4 == NULL) {
100
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
101
 
                                "crypto API arc4\n");
102
 
                goto fail;
103
 
        }
104
 
 
105
 
        priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
106
 
        if (priv->tx_tfm_michael == NULL) {
107
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
108
 
                                "crypto API michael_mic\n");
109
 
                goto fail;
110
 
        }
111
 
 
112
 
        priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
113
 
        if (priv->rx_tfm_arc4 == NULL) {
114
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
115
 
                                "crypto API arc4\n");
116
 
                goto fail;
117
 
        }
118
 
 
119
 
        priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
120
 
        if (priv->rx_tfm_michael == NULL) {
121
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
122
 
                                "crypto API michael_mic\n");
123
 
                goto fail;
124
 
        }
125
 
#else
126
 
        priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
127
 
                        CRYPTO_ALG_ASYNC);
128
 
        if (IS_ERR(priv->tx_tfm_arc4)) {
129
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
130
 
                                "crypto API arc4\n");
131
 
                priv->tx_tfm_arc4 = NULL;
132
 
                goto fail;
133
 
        }
134
 
 
135
 
        priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
136
 
                        CRYPTO_ALG_ASYNC);
137
 
        if (IS_ERR(priv->tx_tfm_michael)) {
138
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
139
 
                                "crypto API michael_mic\n");
140
 
                priv->tx_tfm_michael = NULL;
141
 
                goto fail;
142
 
        }
143
 
 
144
 
        priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
145
 
                        CRYPTO_ALG_ASYNC);
146
 
        if (IS_ERR(priv->rx_tfm_arc4)) {
147
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
148
 
                                "crypto API arc4\n");
149
 
                priv->rx_tfm_arc4 = NULL;
150
 
                goto fail;
151
 
        }
152
 
 
153
 
        priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
154
 
                        CRYPTO_ALG_ASYNC);
155
 
        if (IS_ERR(priv->rx_tfm_michael)) {
156
 
                printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate "
157
 
                                "crypto API michael_mic\n");
158
 
                priv->rx_tfm_michael = NULL;
159
 
                goto fail;
160
 
        }
161
 
#endif
162
 
        return priv;
163
 
 
164
 
fail:
165
 
        if (priv) {
166
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
167
 
                if (priv->tx_tfm_michael)
168
 
                        crypto_free_tfm(priv->tx_tfm_michael);
169
 
                if (priv->tx_tfm_arc4)
170
 
                        crypto_free_tfm(priv->tx_tfm_arc4);
171
 
                if (priv->rx_tfm_michael)
172
 
                        crypto_free_tfm(priv->rx_tfm_michael);
173
 
                if (priv->rx_tfm_arc4)
174
 
                        crypto_free_tfm(priv->rx_tfm_arc4);
175
 
 
176
 
#else
177
 
                if (priv->tx_tfm_michael)
178
 
                        crypto_free_hash(priv->tx_tfm_michael);
179
 
                if (priv->tx_tfm_arc4)
180
 
                        crypto_free_blkcipher(priv->tx_tfm_arc4);
181
 
                if (priv->rx_tfm_michael)
182
 
                        crypto_free_hash(priv->rx_tfm_michael);
183
 
                if (priv->rx_tfm_arc4)
184
 
                        crypto_free_blkcipher(priv->rx_tfm_arc4);
185
 
#endif
186
 
                kfree(priv);
187
 
        }
188
 
 
189
 
        return NULL;
190
 
}
191
 
 
192
 
 
193
 
static void rtllib_tkip_deinit(void *priv)
194
 
{
195
 
        struct rtllib_tkip_data *_priv = priv;
196
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
197
 
        if (_priv->tx_tfm_michael)
198
 
                crypto_free_tfm(_priv->tx_tfm_michael);
199
 
        if (_priv->tx_tfm_arc4)
200
 
                crypto_free_tfm(_priv->tx_tfm_arc4);
201
 
        if (_priv->rx_tfm_michael)
202
 
                crypto_free_tfm(_priv->rx_tfm_michael);
203
 
        if (_priv->rx_tfm_arc4)
204
 
                crypto_free_tfm(_priv->rx_tfm_arc4);
205
 
#else
206
 
        if (_priv) {
207
 
                if (_priv->tx_tfm_michael)
208
 
                        crypto_free_hash(_priv->tx_tfm_michael);
209
 
                if (_priv->tx_tfm_arc4)
210
 
                        crypto_free_blkcipher(_priv->tx_tfm_arc4);
211
 
                if (_priv->rx_tfm_michael)
212
 
                        crypto_free_hash(_priv->rx_tfm_michael);
213
 
                if (_priv->rx_tfm_arc4)
214
 
                        crypto_free_blkcipher(_priv->rx_tfm_arc4);
215
 
        }
216
 
#endif
217
 
        kfree(priv);
218
 
}
219
 
 
220
 
 
221
 
static inline u16 RotR1(u16 val)
222
 
{
223
 
        return (val >> 1) | (val << 15);
224
 
}
225
 
 
226
 
 
227
 
static inline u8 Lo8(u16 val)
228
 
{
229
 
        return val & 0xff;
230
 
}
231
 
 
232
 
 
233
 
static inline u8 Hi8(u16 val)
234
 
{
235
 
        return val >> 8;
236
 
}
237
 
 
238
 
 
239
 
static inline u16 Lo16(u32 val)
240
 
{
241
 
        return val & 0xffff;
242
 
}
243
 
 
244
 
 
245
 
static inline u16 Hi16(u32 val)
246
 
{
247
 
        return val >> 16;
248
 
}
249
 
 
250
 
 
251
 
static inline u16 Mk16(u8 hi, u8 lo)
252
 
{
253
 
        return lo | (((u16) hi) << 8);
254
 
}
255
 
 
256
 
 
257
 
static inline u16 Mk16_le(u16 *v)
258
 
{
259
 
        return le16_to_cpu(*v);
260
 
}
261
 
 
262
 
 
263
 
static const u16 Sbox[256] =
264
 
{
265
 
        0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
266
 
        0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
267
 
        0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
268
 
        0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
269
 
        0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
270
 
        0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
271
 
        0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
272
 
        0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
273
 
        0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
274
 
        0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
275
 
        0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
276
 
        0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
277
 
        0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
278
 
        0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
279
 
        0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
280
 
        0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
281
 
        0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
282
 
        0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
283
 
        0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
284
 
        0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
285
 
        0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
286
 
        0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
287
 
        0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
288
 
        0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
289
 
        0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
290
 
        0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
291
 
        0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
292
 
        0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
293
 
        0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
294
 
        0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
295
 
        0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
296
 
        0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
297
 
};
298
 
 
299
 
 
300
 
static inline u16 _S_(u16 v)
301
 
{
302
 
        u16 t = Sbox[Hi8(v)];
303
 
        return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
304
 
}
305
 
 
306
 
 
307
 
#define PHASE1_LOOP_COUNT 8
308
 
 
309
 
 
310
 
static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
311
 
{
312
 
        int i, j;
313
 
 
314
 
        /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
315
 
        TTAK[0] = Lo16(IV32);
316
 
        TTAK[1] = Hi16(IV32);
317
 
        TTAK[2] = Mk16(TA[1], TA[0]);
318
 
        TTAK[3] = Mk16(TA[3], TA[2]);
319
 
        TTAK[4] = Mk16(TA[5], TA[4]);
320
 
 
321
 
        for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
322
 
                j = 2 * (i & 1);
323
 
                TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
324
 
                TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
325
 
                TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
326
 
                TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
327
 
                TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
328
 
        }
329
 
}
330
 
 
331
 
 
332
 
static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
333
 
                               u16 IV16)
334
 
{
335
 
        /* Make temporary area overlap WEP seed so that the final copy can be
336
 
         * avoided on little endian hosts. */
337
 
        u16 *PPK = (u16 *) &WEPSeed[4];
338
 
 
339
 
        /* Step 1 - make copy of TTAK and bring in TSC */
340
 
        PPK[0] = TTAK[0];
341
 
        PPK[1] = TTAK[1];
342
 
        PPK[2] = TTAK[2];
343
 
        PPK[3] = TTAK[3];
344
 
        PPK[4] = TTAK[4];
345
 
        PPK[5] = TTAK[4] + IV16;
346
 
 
347
 
        /* Step 2 - 96-bit bijective mixing using S-box */
348
 
        PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
349
 
        PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
350
 
        PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
351
 
        PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
352
 
        PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
353
 
        PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
354
 
 
355
 
        PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
356
 
        PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
357
 
        PPK[2] += RotR1(PPK[1]);
358
 
        PPK[3] += RotR1(PPK[2]);
359
 
        PPK[4] += RotR1(PPK[3]);
360
 
        PPK[5] += RotR1(PPK[4]);
361
 
 
362
 
        /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
363
 
         * WEPSeed[0..2] is transmitted as WEP IV */
364
 
        WEPSeed[0] = Hi8(IV16);
365
 
        WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
366
 
        WEPSeed[2] = Lo8(IV16);
367
 
        WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
368
 
 
369
 
#ifdef __BIG_ENDIAN
370
 
        {
371
 
                int i;
372
 
                for (i = 0; i < 6; i++)
373
 
                        PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
374
 
        }
375
 
#endif
376
 
}
377
 
 
378
 
 
379
 
static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
380
 
{
381
 
        struct rtllib_tkip_data *tkey = priv;
382
 
                int len;
383
 
        u8 *pos;
384
 
        struct rtllib_hdr_4addr *hdr;
385
 
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
386
 
 
387
 
        #if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
388
 
        struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
389
 
        int ret = 0;
390
 
        #endif
391
 
        u8 rc4key[16],  *icv;
392
 
        u32 crc;
393
 
#ifdef _RTL8192_EXT_PATCH_      
394
 
        u8 broadcastaddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
395
 
        u8 is_broadcast_data = 0;
396
 
#endif
397
 
        struct scatterlist sg;
398
 
 
399
 
        if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
400
 
            skb->len < hdr_len)
401
 
                return -1;
402
 
 
403
 
        hdr = (struct rtllib_hdr_4addr *) skb->data;
404
 
#ifdef _RTL8192_EXT_PATCH_      
405
 
        if(tcb_desc->badhoc == 0){
406
 
                if(memcmp(hdr->addr1,broadcastaddr,6) == 0){
407
 
                        is_broadcast_data = 1;
408
 
                        tcb_desc->bHwSec = 0;
409
 
                }
410
 
                if(is_multicast_ether_addr(hdr->addr1)){
411
 
                        tcb_desc->bHwSec = 0;
412
 
                }
413
 
        }
414
 
#endif
415
 
#if 0
416
 
printk("@@ tkey\n");
417
 
printk("%x|", ((u32*)tkey->key)[0]);
418
 
printk("%x|", ((u32*)tkey->key)[1]);
419
 
printk("%x|", ((u32*)tkey->key)[2]);
420
 
printk("%x|", ((u32*)tkey->key)[3]);
421
 
printk("%x|", ((u32*)tkey->key)[4]);
422
 
printk("%x|", ((u32*)tkey->key)[5]);
423
 
printk("%x|", ((u32*)tkey->key)[6]);
424
 
printk("%x\n", ((u32*)tkey->key)[7]);
425
 
#endif
426
 
 
427
 
        if (!tcb_desc->bHwSec)
428
 
        {
429
 
                if (!tkey->tx_phase1_done) {
430
 
                        tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
431
 
                                        tkey->tx_iv32);
432
 
                        tkey->tx_phase1_done = 1;
433
 
                }
434
 
                tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
435
 
        }
436
 
        else
437
 
        tkey->tx_phase1_done = 1;
438
 
        
439
 
        
440
 
        len = skb->len - hdr_len;
441
 
        pos = skb_push(skb, 8);
442
 
        memmove(pos, pos + 8, hdr_len);
443
 
        pos += hdr_len;
444
 
 
445
 
        if (tcb_desc->bHwSec)
446
 
        {
447
 
                *pos++ = Hi8(tkey->tx_iv16);
448
 
                *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
449
 
                *pos++ = Lo8(tkey->tx_iv16);
450
 
        }
451
 
        else
452
 
        {
453
 
                *pos++ = rc4key[0];
454
 
                *pos++ = rc4key[1];
455
 
                *pos++ = rc4key[2];
456
 
        }
457
 
 
458
 
        *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
459
 
        *pos++ = tkey->tx_iv32 & 0xff;
460
 
        *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
461
 
        *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
462
 
        *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
463
 
 
464
 
        if (!tcb_desc->bHwSec)
465
 
        {
466
 
                icv = skb_put(skb, 4);
467
 
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
468
 
                crc = ~crc32_le(~0, pos, len);
469
 
#else
470
 
                crc = ~ether_crc_le(len, pos);
471
 
#endif
472
 
                icv[0] = crc;
473
 
                icv[1] = crc >> 8;
474
 
                icv[2] = crc >> 16;
475
 
                icv[3] = crc >> 24;
476
 
 
477
 
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
478
 
                sg.page = virt_to_page(pos);
479
 
                sg.offset = offset_in_page(pos);
480
 
                sg.length = len + 4;
481
 
#else           
482
 
                sg_init_one(&sg, pos, len+4);
483
 
#endif
484
 
 
485
 
 
486
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
487
 
                crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
488
 
                crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
489
 
#else
490
 
                crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
491
 
                ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
492
 
#endif
493
 
 
494
 
        }
495
 
 
496
 
        tkey->tx_iv16++;
497
 
        if (tkey->tx_iv16 == 0) {
498
 
                tkey->tx_phase1_done = 0;
499
 
                tkey->tx_iv32++;
500
 
        }
501
 
 
502
 
        if (!tcb_desc->bHwSec)
503
 
        #if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
504
 
                return 0;
505
 
        #else
506
 
                return ret;
507
 
        #endif
508
 
        else
509
 
                return 0;
510
 
 
511
 
 
512
 
}
513
 
 
514
 
static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
515
 
{
516
 
        struct rtllib_tkip_data *tkey = priv;
517
 
        u8 keyidx, *pos;
518
 
        u32 iv32;
519
 
        u16 iv16;
520
 
        struct rtllib_hdr_4addr *hdr;
521
 
        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
522
 
        #if ( !defined(BUILT_IN_CRYPTO) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED)) )
523
 
        struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
524
 
        #endif
525
 
        u8 rc4key[16];
526
 
        u8 icv[4];
527
 
        u32 crc;
528
 
        struct scatterlist sg;
529
 
        int plen;
530
 
        if (skb->len < hdr_len + 8 + 4)
531
 
                return -1;
532
 
 
533
 
        hdr = (struct rtllib_hdr_4addr *) skb->data;
534
 
        pos = skb->data + hdr_len;
535
 
        keyidx = pos[3];
536
 
        if (!(keyidx & (1 << 5))) {
537
 
                if (net_ratelimit()) {
538
 
                        printk(KERN_DEBUG "TKIP: received packet without ExtIV"
539
 
                               " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
540
 
                }
541
 
                return -2;
542
 
        }
543
 
        keyidx >>= 6;
544
 
        if (tkey->key_idx != keyidx) {
545
 
                printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
546
 
                       "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
547
 
                return -6;
548
 
        }
549
 
        if (!tkey->key_set) {
550
 
                if (net_ratelimit()) {
551
 
                        printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
552
 
                               " with keyid=%d that does not have a configured"
553
 
                               " key\n", MAC_ARG(hdr->addr2), keyidx);
554
 
                }
555
 
                return -3;
556
 
        }
557
 
        iv16 = (pos[0] << 8) | pos[2];
558
 
        iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
559
 
        pos += 8;
560
 
 
561
 
        if (!tcb_desc->bHwSec || (skb->cb[0] == 1))
562
 
        {
563
 
                if ((iv32 < tkey->rx_iv32 ||
564
 
                (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16))&&tkey->initialized) {
565
 
                        if (net_ratelimit()) {
566
 
                                printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
567
 
                                " previous TSC %08x%04x received TSC "
568
 
                                "%08x%04x\n", MAC_ARG(hdr->addr2),
569
 
                                tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
570
 
                        }
571
 
                        tkey->dot11RSNAStatsTKIPReplays++;
572
 
                        return -4;
573
 
                }
574
 
                tkey->initialized = true;
575
 
        
576
 
                if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
577
 
                        tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
578
 
                        tkey->rx_phase1_done = 1;
579
 
                }
580
 
                tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
581
 
        
582
 
                plen = skb->len - hdr_len - 12;
583
 
        
584
 
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
585
 
                sg.page = virt_to_page(pos);
586
 
                sg.offset = offset_in_page(pos);
587
 
                sg.length = plen + 4;
588
 
#else
589
 
                sg_init_one(&sg, pos, plen+4);
590
 
#endif
591
 
 
592
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
593
 
                crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
594
 
                crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
595
 
#else
596
 
                crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
597
 
                if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
598
 
                        if (net_ratelimit()) {
599
 
                                printk(KERN_DEBUG ": TKIP: failed to decrypt "
600
 
                                                "received packet from " MAC_FMT "\n",
601
 
                                                MAC_ARG(hdr->addr2));
602
 
                        }
603
 
                        return -7;
604
 
                }
605
 
#endif
606
 
        
607
 
        #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
608
 
                crc = ~crc32_le(~0, pos, plen);
609
 
        #else
610
 
                crc = ~ether_crc_le(plen, pos);
611
 
        #endif
612
 
                icv[0] = crc;
613
 
                icv[1] = crc >> 8;
614
 
                icv[2] = crc >> 16;
615
 
                icv[3] = crc >> 24;
616
 
        
617
 
                if (memcmp(icv, pos + plen, 4) != 0) {
618
 
                        if (iv32 != tkey->rx_iv32) {
619
 
                                /* Previously cached Phase1 result was already lost, so
620
 
                                * it needs to be recalculated for the next packet. */
621
 
                                tkey->rx_phase1_done = 0;
622
 
                        }
623
 
                        if (net_ratelimit()) {
624
 
                                printk(KERN_DEBUG "TKIP: ICV error detected: STA="
625
 
                                MAC_FMT "\n", MAC_ARG(hdr->addr2));
626
 
                        }
627
 
                        tkey->dot11RSNAStatsTKIPICVErrors++;
628
 
                        return -5;
629
 
                }
630
 
 
631
 
        }
632
 
 
633
 
        /* Update real counters only after Michael MIC verification has
634
 
         * completed */
635
 
        tkey->rx_iv32_new = iv32;
636
 
        tkey->rx_iv16_new = iv16;
637
 
 
638
 
        /* Remove IV and ICV */
639
 
        memmove(skb->data + 8, skb->data, hdr_len);
640
 
        skb_pull(skb, 8);
641
 
        skb_trim(skb, skb->len - 4);
642
 
 
643
 
#ifdef JOHN_DUMP 
644
 
if( ((u16*)skb->data)[0] & 0x4000){
645
 
        printk("@@ rx decrypted skb->data");
646
 
        int i;
647
 
        for(i=0;i<skb->len;i++){
648
 
                if( (i%24)==0 ) printk("\n");
649
 
                printk("%2x ", ((u8*)skb->data)[i]);
650
 
        }
651
 
        printk("\n");
652
 
}
653
 
#endif /*JOHN_DUMP*/
654
 
        return keyidx;
655
 
}
656
 
 
657
 
 
658
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
659
 
static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
660
 
                       u8 *data, size_t data_len, u8 *mic)
661
 
{
662
 
        struct scatterlist sg[2];
663
 
#if ( !defined(BUILT_IN_CRYPTO) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) )
664
 
        struct hash_desc desc;
665
 
        int ret = 0;
666
 
#endif
667
 
 
668
 
        if (tfm_michael == NULL){
669
 
                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
670
 
                return -1;
671
 
        }
672
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
673
 
        sg[0].page = virt_to_page(hdr);
674
 
        sg[0].offset = offset_in_page(hdr);
675
 
        sg[0].length = 16;
676
 
 
677
 
        sg[1].page = virt_to_page(data);
678
 
        sg[1].offset = offset_in_page(data);
679
 
        sg[1].length = data_len;
680
 
#else
681
 
        sg_init_table(sg, 2);
682
 
        sg_set_buf(&sg[0], hdr, 16);
683
 
        sg_set_buf(&sg[1], data, data_len);
684
 
#endif
685
 
 
686
 
#if ( defined(BUILT_IN_CRYPTO) || LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
687
 
        crypto_digest_init(tfm_michael);
688
 
        crypto_digest_setkey(tfm_michael, key, 8);
689
 
        crypto_digest_update(tfm_michael, sg, 2);
690
 
        crypto_digest_final(tfm_michael, mic);
691
 
        return 0;
692
 
#else
693
 
if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
694
 
                return -1;
695
 
 
696
 
              desc.tfm = tkey->tfm_michael;
697
 
              desc.flags = 0;
698
 
              ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
699
 
              return ret;
700
 
#endif
701
 
}
702
 
#else
703
 
static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
704
 
                       u8 * data, size_t data_len, u8 * mic)
705
 
{
706
 
        struct hash_desc desc;
707
 
        struct scatterlist sg[2];
708
 
 
709
 
        if (tfm_michael == NULL) {
710
 
                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
711
 
                return -1;
712
 
        }
713
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
714
 
        sg[0].page = virt_to_page(hdr);
715
 
        sg[0].offset = offset_in_page(hdr);
716
 
        sg[0].length = 16;
717
 
 
718
 
        sg[1].page = virt_to_page(data);
719
 
        sg[1].offset = offset_in_page(data);
720
 
        sg[1].length = data_len;
721
 
#else
722
 
        sg_init_table(sg, 2);
723
 
        sg_set_buf(&sg[0], hdr, 16);
724
 
        sg_set_buf(&sg[1], data, data_len);
725
 
#endif
726
 
 
727
 
        if (crypto_hash_setkey(tfm_michael, key, 8))
728
 
                return -1;
729
 
 
730
 
        desc.tfm = tfm_michael;
731
 
        desc.flags = 0;
732
 
        return crypto_hash_digest(&desc, sg, data_len + 16, mic);
733
 
}
734
 
#endif
735
 
 
736
 
 
737
 
 
738
 
static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
739
 
{
740
 
        struct rtllib_hdr_4addr *hdr11;
741
 
 
742
 
        hdr11 = (struct rtllib_hdr_4addr *) skb->data;
743
 
        switch (le16_to_cpu(hdr11->frame_ctl) &
744
 
                (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
745
 
        case RTLLIB_FCTL_TODS:
746
 
                memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
747
 
                memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
748
 
                break;
749
 
        case RTLLIB_FCTL_FROMDS:
750
 
                memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
751
 
                memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
752
 
                break;
753
 
        case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
754
 
                memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
755
 
                memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
756
 
                break;
757
 
        case 0:
758
 
                memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
759
 
                memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
760
 
                break;
761
 
        }
762
 
                
763
 
        hdr[12] = 0; /* priority */
764
 
        
765
 
        hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
766
 
}
767
 
 
768
 
 
769
 
static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
770
 
{
771
 
        struct rtllib_tkip_data *tkey = priv;
772
 
        u8 *pos;
773
 
        struct rtllib_hdr_4addr *hdr;
774
 
 
775
 
        hdr = (struct rtllib_hdr_4addr *) skb->data;
776
 
 
777
 
        if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
778
 
                printk(KERN_DEBUG "Invalid packet for Michael MIC add "
779
 
                       "(tailroom=%d hdr_len=%d skb->len=%d)\n",
780
 
                       skb_tailroom(skb), hdr_len, skb->len);
781
 
                return -1;
782
 
        }
783
 
 
784
 
        michael_mic_hdr(skb, tkey->tx_hdr);
785
 
 
786
 
        if(RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
787
 
                tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
788
 
        }
789
 
        pos = skb_put(skb, 8);
790
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
791
 
        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
792
 
                                skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
793
 
#else
794
 
        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
795
 
                                skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
796
 
#endif
797
 
                return -1;
798
 
 
799
 
        return 0;
800
 
}
801
 
 
802
 
 
803
 
#if WIRELESS_EXT >= 18
804
 
static void rtllib_michael_mic_failure(struct net_device *dev,
805
 
                                       struct rtllib_hdr_4addr *hdr,
806
 
                                       int keyidx)
807
 
{
808
 
        union iwreq_data wrqu;
809
 
        struct iw_michaelmicfailure ev;
810
 
 
811
 
        /* TODO: needed parameters: count, keyid, key type, TSC */
812
 
        memset(&ev, 0, sizeof(ev));
813
 
        ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
814
 
        if (hdr->addr1[0] & 0x01)
815
 
                ev.flags |= IW_MICFAILURE_GROUP;
816
 
        else
817
 
                ev.flags |= IW_MICFAILURE_PAIRWISE;
818
 
        ev.src_addr.sa_family = ARPHRD_ETHER;
819
 
        memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
820
 
        memset(&wrqu, 0, sizeof(wrqu));
821
 
        wrqu.data.length = sizeof(ev);
822
 
        wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
823
 
}
824
 
#elif WIRELESS_EXT >= 15
825
 
static void rtllib_michael_mic_failure(struct net_device *dev,
826
 
                                       struct rtllib_hdr_4addr *hdr,
827
 
                                       int keyidx)
828
 
{
829
 
        union iwreq_data wrqu;
830
 
        char buf[128];
831
 
 
832
 
        /* TODO: needed parameters: count, keyid, key type, TSC */
833
 
        sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
834
 
                MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
835
 
                MAC_ARG(hdr->addr2));
836
 
        memset(&wrqu, 0, sizeof(wrqu));
837
 
        wrqu.data.length = strlen(buf);
838
 
        wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
839
 
}
840
 
#else /* WIRELESS_EXT >= 15 */
841
 
static inline void rtllib_michael_mic_failure(struct net_device *dev,
842
 
                                              struct rtllib_hdr_4addr *hdr,
843
 
                                              int keyidx)
844
 
{
845
 
}
846
 
#endif /* WIRELESS_EXT >= 15 */
847
 
 
848
 
static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx,
849
 
                                     int hdr_len, void *priv, struct rtllib_device* ieee)
850
 
{
851
 
        struct rtllib_tkip_data *tkey = priv;
852
 
        u8 mic[8];
853
 
        struct rtllib_hdr_4addr *hdr;
854
 
 
855
 
        hdr = (struct rtllib_hdr_4addr *) skb->data;
856
 
 
857
 
        if (!tkey->key_set)
858
 
                return -1;
859
 
 
860
 
        michael_mic_hdr(skb, tkey->rx_hdr);
861
 
        if(RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
862
 
                tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
863
 
        }
864
 
 
865
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
866
 
        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
867
 
                                skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
868
 
#else
869
 
        if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
870
 
                                skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
871
 
#endif 
872
 
                return -1;
873
 
    
874
 
        if ((memcmp(mic, skb->data + skb->len - 8, 8) != 0)||(ieee->force_mic_error)) {
875
 
                struct rtllib_hdr_4addr *hdr;
876
 
                hdr = (struct rtllib_hdr_4addr *) skb->data;
877
 
                printk(KERN_DEBUG "%s: Michael MIC verification failed for "
878
 
                       "MSDU from " MAC_FMT " keyidx=%d\n",
879
 
                       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
880
 
                       keyidx);
881
 
                printk("%d, force_mic_error = %d\n", (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\
882
 
                        ieee->force_mic_error); 
883
 
                if (skb->dev) {
884
 
                        printk("skb->dev != NULL\n");
885
 
                        rtllib_michael_mic_failure(skb->dev, hdr, keyidx);
886
 
                }
887
 
                tkey->dot11RSNAStatsTKIPLocalMICFailures++;
888
 
                ieee->force_mic_error = false;
889
 
                return -1;
890
 
        }
891
 
 
892
 
        /* Update TSC counters for RX now that the packet verification has
893
 
         * completed. */
894
 
        tkey->rx_iv32 = tkey->rx_iv32_new;
895
 
        tkey->rx_iv16 = tkey->rx_iv16_new;
896
 
 
897
 
        skb_trim(skb, skb->len - 8);
898
 
 
899
 
        return 0;
900
 
}
901
 
 
902
 
 
903
 
static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv)
904
 
{
905
 
        struct rtllib_tkip_data *tkey = priv;
906
 
        int keyidx;
907
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
908
 
        struct crypto_tfm *tfm = tkey->tx_tfm_michael;
909
 
        struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
910
 
        struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
911
 
        struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
912
 
#else
913
 
        struct crypto_hash *tfm = tkey->tx_tfm_michael;
914
 
        struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
915
 
        struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
916
 
        struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
917
 
#endif
918
 
 
919
 
        keyidx = tkey->key_idx;
920
 
        memset(tkey, 0, sizeof(*tkey));
921
 
        tkey->key_idx = keyidx;
922
 
#if ( defined(BUILT_IN_CRYPTO) || ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) )
923
 
        tkey->tx_tfm_michael = tfm;
924
 
        tkey->tx_tfm_arc4 = tfm2;
925
 
        tkey->rx_tfm_michael = tfm3;
926
 
        tkey->rx_tfm_arc4 = tfm4;
927
 
#else
928
 
        tkey->tx_tfm_michael = tfm;
929
 
        tkey->tx_tfm_arc4 = tfm2;
930
 
        tkey->rx_tfm_michael = tfm3;
931
 
        tkey->rx_tfm_arc4 = tfm4;
932
 
#endif
933
 
 
934
 
        if (len == TKIP_KEY_LEN) {
935
 
                memcpy(tkey->key, key, TKIP_KEY_LEN);
936
 
                tkey->key_set = 1;
937
 
                tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
938
 
                if (seq) {
939
 
                        tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
940
 
                                (seq[3] << 8) | seq[2];
941
 
                        tkey->rx_iv16 = (seq[1] << 8) | seq[0];
942
 
                }
943
 
        } else if (len == 0)
944
 
                tkey->key_set = 0;
945
 
        else
946
 
                return -1;
947
 
 
948
 
        return 0;
949
 
}
950
 
 
951
 
 
952
 
static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv)
953
 
{
954
 
        struct rtllib_tkip_data *tkey = priv;
955
 
 
956
 
        if (len < TKIP_KEY_LEN)
957
 
                return -1;
958
 
 
959
 
        if (!tkey->key_set)
960
 
                return 0;
961
 
        memcpy(key, tkey->key, TKIP_KEY_LEN);
962
 
 
963
 
        if (seq) {
964
 
                /* Return the sequence number of the last transmitted frame. */
965
 
                u16 iv16 = tkey->tx_iv16;
966
 
                u32 iv32 = tkey->tx_iv32;
967
 
                if (iv16 == 0)
968
 
                        iv32--;
969
 
                iv16--;
970
 
                seq[0] = tkey->tx_iv16;
971
 
                seq[1] = tkey->tx_iv16 >> 8;
972
 
                seq[2] = tkey->tx_iv32;
973
 
                seq[3] = tkey->tx_iv32 >> 8;
974
 
                seq[4] = tkey->tx_iv32 >> 16;
975
 
                seq[5] = tkey->tx_iv32 >> 24;
976
 
        }
977
 
 
978
 
        return TKIP_KEY_LEN;
979
 
}
980
 
 
981
 
 
982
 
static char * rtllib_tkip_print_stats(char *p, void *priv)
983
 
{
984
 
        struct rtllib_tkip_data *tkip = priv;
985
 
        p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
986
 
                     "tx_pn=%02x%02x%02x%02x%02x%02x "
987
 
                     "rx_pn=%02x%02x%02x%02x%02x%02x "
988
 
                     "replays=%d icv_errors=%d local_mic_failures=%d\n",
989
 
                     tkip->key_idx, tkip->key_set,
990
 
                     (tkip->tx_iv32 >> 24) & 0xff,
991
 
                     (tkip->tx_iv32 >> 16) & 0xff,
992
 
                     (tkip->tx_iv32 >> 8) & 0xff,
993
 
                     tkip->tx_iv32 & 0xff,
994
 
                     (tkip->tx_iv16 >> 8) & 0xff,
995
 
                     tkip->tx_iv16 & 0xff,
996
 
                     (tkip->rx_iv32 >> 24) & 0xff,
997
 
                     (tkip->rx_iv32 >> 16) & 0xff,
998
 
                     (tkip->rx_iv32 >> 8) & 0xff,
999
 
                     tkip->rx_iv32 & 0xff,
1000
 
                     (tkip->rx_iv16 >> 8) & 0xff,
1001
 
                     tkip->rx_iv16 & 0xff,
1002
 
                     tkip->dot11RSNAStatsTKIPReplays,
1003
 
                     tkip->dot11RSNAStatsTKIPICVErrors,
1004
 
                     tkip->dot11RSNAStatsTKIPLocalMICFailures);
1005
 
        return p;
1006
 
}
1007
 
 
1008
 
 
1009
 
static struct rtllib_crypto_ops rtllib_crypt_tkip = {
1010
 
        .name                   = "TKIP",
1011
 
        .init                   = rtllib_tkip_init,
1012
 
        .deinit                 = rtllib_tkip_deinit,
1013
 
        .encrypt_mpdu           = rtllib_tkip_encrypt,
1014
 
        .decrypt_mpdu           = rtllib_tkip_decrypt,
1015
 
        .encrypt_msdu           = rtllib_michael_mic_add,
1016
 
        .decrypt_msdu           = rtllib_michael_mic_verify,
1017
 
        .set_key                = rtllib_tkip_set_key,
1018
 
        .get_key                = rtllib_tkip_get_key,
1019
 
        .print_stats            = rtllib_tkip_print_stats,
1020
 
        .extra_prefix_len       = 4 + 4, /* IV + ExtIV */
1021
 
        .extra_postfix_len      = 8 + 4, /* MIC + ICV */
1022
 
        .owner                  = THIS_MODULE,
1023
 
};
1024
 
 
1025
 
 
1026
 
int __init rtllib_crypto_tkip_init(void)
1027
 
{
1028
 
        return rtllib_register_crypto_ops(&rtllib_crypt_tkip);
1029
 
}
1030
 
 
1031
 
 
1032
 
void __exit rtllib_crypto_tkip_exit(void)
1033
 
{
1034
 
        rtllib_unregister_crypto_ops(&rtllib_crypt_tkip);
1035
 
}
1036
 
 
1037
 
void rtllib_tkip_null(void)
1038
 
{
1039
 
        return;
1040
 
}
1041
 
 
1042
 
#ifndef BUILT_IN_RTLLIB
1043
 
EXPORT_SYMBOL_RSL(rtllib_tkip_null);
1044
 
 
1045
 
module_init(rtllib_crypto_tkip_init);
1046
 
module_exit(rtllib_crypto_tkip_exit);
1047
 
#endif