]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/rt2860/common/cmm_wep.c
Staging: rt28x0: updates from vendor's V2.1.0.0 drivers
[net-next-2.6.git] / drivers / staging / rt2860 / 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 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 UCHAR   WEPKEY[] = {
110                 //IV
111                 0x00, 0x11, 0x22,
112                 //WEP KEY
113                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
114         };
115  */
116
117 /*
118         ========================================================================
119
120         Routine Description:
121                 Init WEP function.
122
123         Arguments:
124       pAd               Pointer to our adapter
125                 pKey        Pointer to the WEP KEY
126                 KeyId              WEP Key ID
127                 KeyLen      the length of WEP KEY
128                 pDest       Pointer to the destination which Encryption data will store in.
129
130         Return Value:
131                 None
132
133         IRQL = DISPATCH_LEVEL
134
135         Note:
136
137         ========================================================================
138 */
139 VOID    RTMPInitWepEngine(
140         IN      PRTMP_ADAPTER   pAd,
141         IN      PUCHAR                  pKey,
142         IN      UCHAR                   KeyId,
143         IN      UCHAR                   KeyLen,
144         IN OUT  PUCHAR          pDest)
145 {
146         UINT i;
147         UCHAR   WEPKEY[] = {
148                 //IV
149                 0x00, 0x11, 0x22,
150                 //WEP KEY
151                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
152         };
153
154         pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
155
156     {
157                 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
158
159         for(i = 0; i < 3; i++)
160                         WEPKEY[i] = RandomByte(pAd);   //Call mlme RandomByte() function.
161                 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);  //INIT SBOX, KEYLEN+3(IV)
162
163                 NdisMoveMemory(pDest, WEPKEY, 3);  //Append Init Vector
164     }
165         *(pDest+3) = (KeyId << 6);       //Append KEYID
166
167 }
168
169 /*
170         ========================================================================
171
172         Routine Description:
173                 Encrypt transimitted data
174
175         Arguments:
176       pAd               Pointer to our adapter
177       pSrc        Pointer to the transimitted source data that will be encrypt
178       pDest       Pointer to the destination where entryption data will be store in.
179       Len                       Indicate the length of the source data
180
181         Return Value:
182       None
183
184         IRQL = DISPATCH_LEVEL
185
186         Note:
187
188         ========================================================================
189 */
190 VOID    RTMPEncryptData(
191         IN      PRTMP_ADAPTER   pAd,
192         IN      PUCHAR                  pSrc,
193         IN      PUCHAR                  pDest,
194         IN      UINT                    Len)
195 {
196         pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
197         ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
198 }
199
200
201 /*
202         ========================================================================
203
204         Routine Description:
205                 Decrypt received WEP data
206
207         Arguments:
208                 pAdapter                Pointer to our adapter
209                 pSrc        Pointer to the received data
210                 Len         the length of the received data
211
212         Return Value:
213                 TRUE        Decrypt WEP data success
214                 FALSE       Decrypt WEP data failed
215
216         Note:
217
218         ========================================================================
219 */
220 BOOLEAN RTMPSoftDecryptWEP(
221         IN PRTMP_ADAPTER        pAd,
222         IN PUCHAR                       pData,
223         IN ULONG                        DataByteCnt,
224         IN PCIPHER_KEY          pGroupKey)
225 {
226         UINT    trailfcs;
227         UINT    crc32;
228         UCHAR   KeyIdx;
229         UCHAR   WEPKEY[] = {
230                 //IV
231                 0x00, 0x11, 0x22,
232                 //WEP KEY
233                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
234         };
235         UCHAR   *pPayload = (UCHAR *)pData + LENGTH_802_11;
236         ULONG   payload_len = DataByteCnt - LENGTH_802_11;
237
238         NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
239
240         KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
241         if (pGroupKey[KeyIdx].KeyLen == 0)
242                 return (FALSE);
243
244         NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
245         ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
246         ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
247         NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
248         crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);  //Skip last 4 bytes(FCS).
249         crc32 ^= 0xffffffff;             /* complement */
250
251     if(crc32 != cpu2le32(trailfcs))
252     {
253                 DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n"));  //CRC error.
254                 return (FALSE);
255         }
256         return (TRUE);
257 }
258
259 /*
260         ========================================================================
261
262         Routine Description:
263                 The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
264
265         Arguments:
266            Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
267                 pKey        Pointer to the WEP KEY
268                 KeyLen      Indicate the length fo the WEP KEY
269
270         Return Value:
271            None
272
273         IRQL = DISPATCH_LEVEL
274
275         Note:
276
277         ========================================================================
278 */
279 VOID    ARCFOUR_INIT(
280         IN      PARCFOURCONTEXT Ctx,
281         IN      PUCHAR                  pKey,
282         IN      UINT                    KeyLen)
283 {
284         UCHAR   t, u;
285         UINT    keyindex;
286         UINT    stateindex;
287         PUCHAR  state;
288         UINT    counter;
289
290         state = Ctx->STATE;
291         Ctx->X = 0;
292         Ctx->Y = 0;
293         for (counter = 0; counter < 256; counter++)
294                 state[counter] = (UCHAR)counter;
295         keyindex = 0;
296         stateindex = 0;
297         for (counter = 0; counter < 256; counter++)
298         {
299                 t = state[counter];
300                 stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
301                 u = state[stateindex];
302                 state[stateindex] = t;
303                 state[counter] = u;
304                 if (++keyindex >= KeyLen)
305                         keyindex = 0;
306         }
307 }
308
309 /*
310         ========================================================================
311
312         Routine Description:
313                 Get bytes from ARCFOUR CONTEXT (S-BOX)
314
315         Arguments:
316            Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
317
318         Return Value:
319            UCHAR  - the value of the ARCFOUR CONTEXT (S-BOX)
320
321         Note:
322
323         ========================================================================
324 */
325 UCHAR   ARCFOUR_BYTE(
326         IN      PARCFOURCONTEXT         Ctx)
327 {
328   UINT x;
329   UINT y;
330   UCHAR sx, sy;
331   PUCHAR state;
332
333   state = Ctx->STATE;
334   x = (Ctx->X + 1) & 0xff;
335   sx = state[x];
336   y = (sx + Ctx->Y) & 0xff;
337   sy = state[y];
338   Ctx->X = x;
339   Ctx->Y = y;
340   state[y] = sx;
341   state[x] = sy;
342
343   return(state[(sx + sy) & 0xff]);
344
345 }
346
347 /*
348         ========================================================================
349
350         Routine Description:
351                 The Stream Cipher Decryption Algorithm
352
353         Arguments:
354                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
355                 pDest                   Pointer to the Destination
356                 pSrc        Pointer to the Source data
357                 Len         Indicate the length of the Source data
358
359         Return Value:
360                 None
361
362         Note:
363
364         ========================================================================
365 */
366 VOID    ARCFOUR_DECRYPT(
367         IN      PARCFOURCONTEXT Ctx,
368         IN      PUCHAR                  pDest,
369         IN      PUCHAR                  pSrc,
370         IN      UINT                    Len)
371 {
372         UINT i;
373
374         for (i = 0; i < Len; i++)
375                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
376 }
377
378 /*
379         ========================================================================
380
381         Routine Description:
382                 The Stream Cipher Encryption Algorithm
383
384         Arguments:
385                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
386                 pDest                   Pointer to the Destination
387                 pSrc        Pointer to the Source data
388                 Len         Indicate the length of the Source dta
389
390         Return Value:
391                 None
392
393         IRQL = DISPATCH_LEVEL
394
395         Note:
396
397         ========================================================================
398 */
399 VOID    ARCFOUR_ENCRYPT(
400         IN      PARCFOURCONTEXT Ctx,
401         IN      PUCHAR                  pDest,
402         IN      PUCHAR                  pSrc,
403         IN      UINT                    Len)
404 {
405         UINT i;
406
407         for (i = 0; i < Len; i++)
408                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
409 }
410
411 /*
412         ========================================================================
413
414         Routine Description:
415                 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
416
417         Arguments:
418                 Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
419                 pDest                   Pointer to the Destination
420                 pSrc        Pointer to the Source data
421                 Len         Indicate the length of the Source dta
422
423
424         ========================================================================
425 */
426
427 VOID    WPAARCFOUR_ENCRYPT(
428         IN      PARCFOURCONTEXT Ctx,
429         IN      PUCHAR                  pDest,
430         IN      PUCHAR                  pSrc,
431         IN      UINT                    Len)
432 {
433         UINT i;
434         //discard first 256 bytes
435         for (i = 0; i < 256; i++)
436             ARCFOUR_BYTE(Ctx);
437
438         for (i = 0; i < Len; i++)
439                 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
440 }
441
442
443 /*
444         ========================================================================
445
446         Routine Description:
447                 Calculate a new FCS given the current FCS and the new data.
448
449         Arguments:
450                 Fcs           the original FCS value
451                 Cp          pointer to the data which will be calculate the FCS
452                 Len         the length of the data
453
454         Return Value:
455                 UINT - FCS 32 bits
456
457         IRQL = DISPATCH_LEVEL
458
459         Note:
460
461         ========================================================================
462 */
463 UINT    RTMP_CALC_FCS32(
464         IN      UINT    Fcs,
465         IN      PUCHAR  Cp,
466         IN      INT             Len)
467 {
468         while (Len--)
469            Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
470
471         return (Fcs);
472 }
473
474
475 /*
476         ========================================================================
477
478         Routine Description:
479                 Get last FCS and encrypt it to the destination
480
481         Arguments:
482                 pDest                   Pointer to the Destination
483
484         Return Value:
485                 None
486
487         Note:
488
489         ========================================================================
490 */
491 VOID    RTMPSetICV(
492         IN      PRTMP_ADAPTER   pAd,
493         IN      PUCHAR  pDest)
494 {
495         pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;             /* complement */
496         pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
497
498         ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
499 }