Staging: add rt2870 wireless driver
[linux-2.6/mini2440.git] / drivers / staging / rt2870 / common / rtmp_wep.c
blob62f9e58729d7e7be4362dc0b7285ea58ad4abf98
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 rtmp_wep.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 10-28-02 Initial
38 #include "../rt_config.h"
40 UINT FCSTAB_32[256] =
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
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
118 ========================================================================
120 Routine Description:
121 Init WEP function.
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.
130 Return Value:
131 None
133 IRQL = DISPATCH_LEVEL
135 Note:
137 ========================================================================
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)
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
154 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
156 #ifdef CONFIG_STA_SUPPORT
157 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
159 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
160 NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
162 else
163 #endif // CONFIG_STA_SUPPORT //
165 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
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)
171 NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
173 *(pDest+3) = (KeyId << 6); //Append KEYID
178 ========================================================================
180 Routine Description:
181 Encrypt transimitted data
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
189 Return Value:
190 None
192 IRQL = DISPATCH_LEVEL
194 Note:
196 ========================================================================
198 VOID RTMPEncryptData(
199 IN PRTMP_ADAPTER pAd,
200 IN PUCHAR pSrc,
201 IN PUCHAR pDest,
202 IN UINT Len)
204 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
205 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
210 ========================================================================
212 Routine Description:
213 Decrypt received WEP data
215 Arguments:
216 pAdapter Pointer to our adapter
217 pSrc Pointer to the received data
218 Len the length of the received data
220 Return Value:
221 TRUE Decrypt WEP data success
222 FALSE Decrypt WEP data failed
224 Note:
226 ========================================================================
228 BOOLEAN RTMPSoftDecryptWEP(
229 IN PRTMP_ADAPTER pAd,
230 IN PUCHAR pData,
231 IN ULONG DataByteCnt,
232 IN PCIPHER_KEY pGroupKey)
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
243 UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
244 ULONG payload_len = DataByteCnt - LENGTH_802_11;
246 NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
248 KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
249 if (pGroupKey[KeyIdx].KeyLen == 0)
250 return (FALSE);
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 */
259 if(crc32 != cpu2le32(trailfcs))
261 DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
262 return (FALSE);
264 return (TRUE);
268 ========================================================================
270 Routine Description:
271 The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
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
278 Return Value:
279 None
281 IRQL = DISPATCH_LEVEL
283 Note:
285 ========================================================================
287 VOID ARCFOUR_INIT(
288 IN PARCFOURCONTEXT Ctx,
289 IN PUCHAR pKey,
290 IN UINT KeyLen)
292 UCHAR t, u;
293 UINT keyindex;
294 UINT stateindex;
295 PUCHAR state;
296 UINT counter;
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++)
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;
318 ========================================================================
320 Routine Description:
321 Get bytes from ARCFOUR CONTEXT (S-BOX)
323 Arguments:
324 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
326 Return Value:
327 UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
329 Note:
331 ========================================================================
333 UCHAR ARCFOUR_BYTE(
334 IN PARCFOURCONTEXT Ctx)
336 UINT x;
337 UINT y;
338 UCHAR sx, sy;
339 PUCHAR state;
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;
351 return(state[(sx + sy) & 0xff]);
356 ========================================================================
358 Routine Description:
359 The Stream Cipher Decryption Algorithm
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
367 Return Value:
368 None
370 Note:
372 ========================================================================
374 VOID ARCFOUR_DECRYPT(
375 IN PARCFOURCONTEXT Ctx,
376 IN PUCHAR pDest,
377 IN PUCHAR pSrc,
378 IN UINT Len)
380 UINT i;
382 for (i = 0; i < Len; i++)
383 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
387 ========================================================================
389 Routine Description:
390 The Stream Cipher Encryption Algorithm
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
398 Return Value:
399 None
401 IRQL = DISPATCH_LEVEL
403 Note:
405 ========================================================================
407 VOID ARCFOUR_ENCRYPT(
408 IN PARCFOURCONTEXT Ctx,
409 IN PUCHAR pDest,
410 IN PUCHAR pSrc,
411 IN UINT Len)
413 UINT i;
415 for (i = 0; i < Len; i++)
416 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
420 ========================================================================
422 Routine Description:
423 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
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
432 ========================================================================
435 VOID WPAARCFOUR_ENCRYPT(
436 IN PARCFOURCONTEXT Ctx,
437 IN PUCHAR pDest,
438 IN PUCHAR pSrc,
439 IN UINT Len)
441 UINT i;
442 //discard first 256 bytes
443 for (i = 0; i < 256; i++)
444 ARCFOUR_BYTE(Ctx);
446 for (i = 0; i < Len; i++)
447 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
452 ========================================================================
454 Routine Description:
455 Calculate a new FCS given the current FCS and the new data.
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
462 Return Value:
463 UINT - FCS 32 bits
465 IRQL = DISPATCH_LEVEL
467 Note:
469 ========================================================================
471 UINT RTMP_CALC_FCS32(
472 IN UINT Fcs,
473 IN PUCHAR Cp,
474 IN INT Len)
476 while (Len--)
477 Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
479 return (Fcs);
484 ========================================================================
486 Routine Description:
487 Get last FCS and encrypt it to the destination
489 Arguments:
490 pDest Pointer to the Destination
492 Return Value:
493 None
495 Note:
497 ========================================================================
499 VOID RTMPSetICV(
500 IN PRTMP_ADAPTER pAd,
501 IN PUCHAR pDest)
503 pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
504 pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
506 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);