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