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