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