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