• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
RTMPInitWepEngine(IN PRTMP_ADAPTER pAd,IN PUCHAR pKey,IN UCHAR KeyId,IN UCHAR KeyLen,IN OUT PUCHAR pDest)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 */
RTMPEncryptData(IN PRTMP_ADAPTER pAd,IN PUCHAR pSrc,IN PUCHAR pDest,IN UINT Len)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 */
RTMPSoftDecryptWEP(IN PRTMP_ADAPTER pAd,IN PUCHAR pData,IN ULONG DataByteCnt,IN PCIPHER_KEY pGroupKey)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 */
ARCFOUR_INIT(IN PARCFOURCONTEXT Ctx,IN PUCHAR pKey,IN UINT KeyLen)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 */
ARCFOUR_BYTE(IN PARCFOURCONTEXT Ctx)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 */
ARCFOUR_DECRYPT(IN PARCFOURCONTEXT Ctx,IN PUCHAR pDest,IN PUCHAR pSrc,IN UINT Len)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 */
ARCFOUR_ENCRYPT(IN PARCFOURCONTEXT Ctx,IN PUCHAR pDest,IN PUCHAR pSrc,IN UINT Len)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 
WPAARCFOUR_ENCRYPT(IN PARCFOURCONTEXT Ctx,IN PUCHAR pDest,IN PUCHAR pSrc,IN UINT Len)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 */
RTMP_CALC_FCS32(IN UINT Fcs,IN PUCHAR Cp,IN INT Len)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 */
RTMPSetICV(IN PRTMP_ADAPTER pAd,IN PUCHAR pDest)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 
509