Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[linux-2.6] / drivers / staging / rt2860 / common / rtmp_wep.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         rtmp_wep.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         Paul Wu         10-28-02                Initial
36 */
37
38 #include "../rt_config.h"
39
40 UINT FCSTAB_32[256] =
41 {
42         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
43         0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
44         0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
45         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
46         0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
47         0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
48         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
49         0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
50         0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
51         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
52         0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
53         0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
54         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
55         0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
56         0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
57         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
58         0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
59         0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
60         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
61         0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
62         0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
63         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
64         0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
65         0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
66         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
67         0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
68         0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
69         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
70         0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
71         0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
72         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
73         0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
74         0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
75         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
76         0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
77         0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
78         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
79         0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
80         0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
81         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
82         0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
83         0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
84         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
85         0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
86         0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
87         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
88         0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
89         0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
90         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
91         0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
92         0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
93         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
94         0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
95         0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
96         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
97         0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
98         0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
99         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
100         0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
101         0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
102         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
103         0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
104         0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
105         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
106 };
107
108 /*
109         ========================================================================
110
111         Routine Description:
112                 Init WEP function.
113
114         Arguments:
115       pAd               Pointer to our adapter
116                 pKey        Pointer to the WEP KEY
117                 KeyId              WEP Key ID
118                 KeyLen      the length of WEP KEY
119                 pDest       Pointer to the destination which Encryption data will store in.
120
121         Return Value:
122                 None
123
124         IRQL = DISPATCH_LEVEL
125
126         Note:
127
128         ========================================================================
129 */
130 VOID    RTMPInitWepEngine(
131         IN      PRTMP_ADAPTER   pAd,
132         IN      PUCHAR                  pKey,
133         IN      UCHAR                   KeyId,
134         IN      UCHAR                   KeyLen,
135         IN OUT  PUCHAR          pDest)
136 {
137         UINT i;
138         UCHAR   WEPKEY[] = {
139                 //IV
140                 0x00, 0x11, 0x22,
141                 //WEP KEY
142                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
143         };
144
145         pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
146
147 #ifdef CONFIG_STA_SUPPORT
148     if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
149     {
150         ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen);  //INIT SBOX, KEYLEN+3(IV)
151         NdisMoveMemory(pDest, pKey, 3);  //Append Init Vector
152     }
153     else
154 #endif // CONFIG_STA_SUPPORT //
155     {
156                 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
157
158         for(i = 0; i < 3; i++)
159                         WEPKEY[i] = RandomByte(pAd);   //Call mlme RandomByte() function.
160                 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);  //INIT SBOX, KEYLEN+3(IV)
161
162                 NdisMoveMemory(pDest, WEPKEY, 3);  //Append Init Vector
163     }
164         *(pDest+3) = (KeyId << 6);       //Append KEYID
165
166 }
167
168 /*
169         ========================================================================
170
171         Routine Description:
172                 Encrypt transimitted data
173
174         Arguments:
175       pAd               Pointer to our adapter
176       pSrc        Pointer to the transimitted source data that will be encrypt
177       pDest       Pointer to the destination where entryption data will be store in.
178       Len                       Indicate the length of the source data
179
180         Return Value:
181       None
182
183         IRQL = DISPATCH_LEVEL
184
185         Note:
186
187         ========================================================================
188 */
189 VOID    RTMPEncryptData(
190         IN      PRTMP_ADAPTER   pAd,
191         IN      PUCHAR                  pSrc,
192         IN      PUCHAR                  pDest,
193         IN      UINT                    Len)
194 {
195         pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
196         ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
197 }
198
199
200 /*
201         ========================================================================
202
203         Routine Description:
204                 Decrypt received WEP data
205
206         Arguments:
207                 pAdapter                Pointer to our adapter
208                 pSrc        Pointer to the received data
209                 Len         the length of the received data
210
211         Return Value:
212                 TRUE        Decrypt WEP data success
213                 FALSE       Decrypt WEP data failed
214
215         Note:
216
217         ========================================================================
218 */
219 BOOLEAN RTMPSoftDecryptWEP(
220         IN PRTMP_ADAPTER        pAd,
221         IN PUCHAR                       pData,
222         IN ULONG                        DataByteCnt,
223         IN PCIPHER_KEY          pGroupKey)
224 {
225         UINT    trailfcs;
226         UINT    crc32;
227         UCHAR   KeyIdx;
228         UCHAR   WEPKEY[] = {
229                 //IV
230                 0x00, 0x11, 0x22,
231                 //WEP KEY
232                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
233         };
234         UCHAR   *pPayload = (UCHAR *)pData + LENGTH_802_11;
235         ULONG   payload_len = DataByteCnt - LENGTH_802_11;
236
237         NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
238
239         KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
240         if (pGroupKey[KeyIdx].KeyLen == 0)
241                 return (FALSE);
242
243         NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
244         ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
245         ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
246         NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
247         crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);  //Skip last 4 bytes(FCS).
248         crc32 ^= 0xffffffff;             /* complement */
249
250     if(crc32 != cpu2le32(trailfcs))
251     {
252                 DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n"));  //CRC error.
253                 return (FALSE);
254         }
255         return (TRUE);
256 }
257
258 /*
259         ========================================================================
260
261         Routine Description:
262                 The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
263
264         Arguments:
265            Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
266                 pKey        Pointer to the WEP KEY
267                 KeyLen      Indicate the length fo the WEP KEY
268
269         Return Value:
270            None
271
272         IRQL = DISPATCH_LEVEL
273
274         Note:
275
276         ========================================================================
277 */
278 VOID    ARCFOUR_INIT(
279         IN      PARCFOURCONTEXT Ctx,
280         IN      PUCHAR                  pKey,
281         IN      UINT                    KeyLen)
282 {
283         UCHAR   t, u;
284         UINT    keyindex;
285         UINT    stateindex;
286         PUCHAR  state;
287         UINT    counter;
288
289         state = Ctx->STATE;
290         Ctx->X = 0;
291         Ctx->Y = 0;
292         for (counter = 0; counter < 256; counter++)
293                 state[counter] = (UCHAR)counter;
294         keyindex = 0;
295         stateindex = 0;
296         for (counter = 0; counter < 256; counter++)
297         {
298                 t = state[counter];
299                 stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
300                 u = state[stateindex];
301                 state[stateindex] = t;
302                 state[counter] = u;
303                 if (++keyindex >= KeyLen)
304                         keyindex = 0;
305         }
306 }
307
308 /*
309         ========================================================================
310
311         Routine Description:
312                 Get bytes from ARCFOUR CONTEXT (S-BOX)
313
314         Arguments:
315            Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
316
317         Return Value:
318            UCHAR  - the value of the ARCFOUR CONTEXT (S-BOX)
319
320         Note:
321
322         ========================================================================
323 */
324 UCHAR   ARCFOUR_BYTE(
325         IN      PARCFOURCONTEXT         Ctx)
326 {
327   UINT x;
328   UINT y;
329   UCHAR sx, sy;
330   PUCHAR state;
331
332   state = Ctx->STATE;
333   x = (Ctx->X + 1) & 0xff;
334   sx = state[x];
335   y = (sx + Ctx->Y) & 0xff;
336   sy = state[y];
337   Ctx->X = x;
338   Ctx->Y = y;
339   state[y] = sx;
340   state[x] = sy;
341
342   return(state[(sx + sy) & 0xff]);
343
344 }
345
346 /*
347         ========================================================================
348
349         Routine Description:
350                 The Stream Cipher Decryption Algorithm
351
352         Arguments:
353                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
354                 pDest                   Pointer to the Destination
355                 pSrc        Pointer to the Source data
356                 Len         Indicate the length of the Source data
357
358         Return Value:
359                 None
360
361         Note:
362
363         ========================================================================
364 */
365 VOID    ARCFOUR_DECRYPT(
366         IN      PARCFOURCONTEXT Ctx,
367         IN      PUCHAR                  pDest,
368         IN      PUCHAR                  pSrc,
369         IN      UINT                    Len)
370 {
371         UINT i;
372
373         for (i = 0; i < Len; i++)
374                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
375 }
376
377 /*
378         ========================================================================
379
380         Routine Description:
381                 The Stream Cipher Encryption Algorithm
382
383         Arguments:
384                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
385                 pDest                   Pointer to the Destination
386                 pSrc        Pointer to the Source data
387                 Len         Indicate the length of the Source dta
388
389         Return Value:
390                 None
391
392         IRQL = DISPATCH_LEVEL
393
394         Note:
395
396         ========================================================================
397 */
398 VOID    ARCFOUR_ENCRYPT(
399         IN      PARCFOURCONTEXT Ctx,
400         IN      PUCHAR                  pDest,
401         IN      PUCHAR                  pSrc,
402         IN      UINT                    Len)
403 {
404         UINT i;
405
406         for (i = 0; i < Len; i++)
407                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
408 }
409
410 /*
411         ========================================================================
412
413         Routine Description:
414                 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
415
416         Arguments:
417                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
418                 pDest                   Pointer to the Destination
419                 pSrc        Pointer to the Source data
420                 Len         Indicate the length of the Source dta
421
422
423         ========================================================================
424 */
425
426 VOID    WPAARCFOUR_ENCRYPT(
427         IN      PARCFOURCONTEXT Ctx,
428         IN      PUCHAR                  pDest,
429         IN      PUCHAR                  pSrc,
430         IN      UINT                    Len)
431 {
432         UINT i;
433         //discard first 256 bytes
434         for (i = 0; i < 256; i++)
435             ARCFOUR_BYTE(Ctx);
436
437         for (i = 0; i < Len; i++)
438                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
439 }
440
441
442 /*
443         ========================================================================
444
445         Routine Description:
446                 Calculate a new FCS given the current FCS and the new data.
447
448         Arguments:
449                 Fcs           the original FCS value
450                 Cp          pointer to the data which will be calculate the FCS
451                 Len         the length of the data
452
453         Return Value:
454                 UINT - FCS 32 bits
455
456         IRQL = DISPATCH_LEVEL
457
458         Note:
459
460         ========================================================================
461 */
462 UINT    RTMP_CALC_FCS32(
463         IN      UINT    Fcs,
464         IN      PUCHAR  Cp,
465         IN      INT             Len)
466 {
467         while (Len--)
468            Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
469
470         return (Fcs);
471 }
472
473
474 /*
475         ========================================================================
476
477         Routine Description:
478                 Get last FCS and encrypt it to the destination
479
480         Arguments:
481                 pDest                   Pointer to the Destination
482
483         Return Value:
484                 None
485
486         Note:
487
488         ========================================================================
489 */
490 VOID    RTMPSetICV(
491         IN      PRTMP_ADAPTER   pAd,
492         IN      PUCHAR  pDest)
493 {
494         pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;             /* complement */
495         pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
496
497         ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
498 }
499