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 u32 FCSTAB_32[256] = {
41 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
42 	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
43 	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
44 	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
45 	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
46 	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
47 	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
48 	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
49 	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
50 	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
51 	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
52 	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
53 	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
54 	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
55 	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
56 	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
57 	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
58 	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
59 	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
60 	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
61 	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
62 	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
63 	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
64 	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
65 	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
66 	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
67 	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
68 	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
69 	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
70 	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
71 	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
72 	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
73 	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
74 	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
75 	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
76 	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
77 	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
78 	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
79 	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
80 	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
81 	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
82 	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
83 	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
84 	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
85 	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
86 	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
87 	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
88 	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
89 	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
90 	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
91 	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
92 	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
93 	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
94 	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
95 	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
96 	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
97 	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
98 	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
99 	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
100 	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
101 	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
102 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
103 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
104 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
105 };
106 
107 /*
108 u8   WEPKEY[] = {
109 		//IV
110 		0x00, 0x11, 0x22,
111 		//WEP KEY
112 		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
113 	};
114  */
115 
116 /*
117 	========================================================================
118 
119 	Routine	Description:
120 		Init WEP function.
121 
122 	Arguments:
123       pAd		Pointer to our adapter
124 		pKey        Pointer to the WEP KEY
125 		KeyId		   WEP Key ID
126 		KeyLen      the length of WEP KEY
127 		pDest       Pointer to the destination which Encryption data will store in.
128 
129 	Return Value:
130 		None
131 
132 	IRQL = DISPATCH_LEVEL
133 
134 	Note:
135 
136 	========================================================================
137 */
RTMPInitWepEngine(struct rt_rtmp_adapter * pAd,u8 * pKey,u8 KeyId,u8 KeyLen,IN u8 * pDest)138 void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
139 		       u8 *pKey,
140 		       u8 KeyId, u8 KeyLen, IN u8 *pDest)
141 {
142 	u32 i;
143 	u8 WEPKEY[] = {
144 		/*IV */
145 		0x00, 0x11, 0x22,
146 		/*WEP KEY */
147 		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
148 		    0xAA, 0xBB, 0xCC
149 	};
150 
151 	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
152 
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 */
RTMPEncryptData(struct rt_rtmp_adapter * pAd,u8 * pSrc,u8 * pDest,u32 Len)187 void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
188 		     u8 *pSrc, u8 *pDest, u32 Len)
189 {
190 	pAd->PrivateInfo.FCSCRC32 =
191 	    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
192 	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
193 }
194 
195 /*
196 	========================================================================
197 
198 	Routine	Description:
199 		Decrypt received WEP data
200 
201 	Arguments:
202 		pAdapter		Pointer to our adapter
203 		pSrc        Pointer to the received data
204 		Len         the length of the received data
205 
206 	Return Value:
207 		TRUE        Decrypt WEP data success
208 		FALSE       Decrypt WEP data failed
209 
210 	Note:
211 
212 	========================================================================
213 */
RTMPSoftDecryptWEP(struct rt_rtmp_adapter * pAd,u8 * pData,unsigned long DataByteCnt,struct rt_cipher_key * pGroupKey)214 BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
215 			   u8 *pData,
216 			   unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey)
217 {
218 	u32 trailfcs;
219 	u32 crc32;
220 	u8 KeyIdx;
221 	u8 WEPKEY[] = {
222 		/*IV */
223 		0x00, 0x11, 0x22,
224 		/*WEP KEY */
225 		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
226 		    0xAA, 0xBB, 0xCC
227 	};
228 	u8 *pPayload = (u8 *) pData + LENGTH_802_11;
229 	unsigned long payload_len = DataByteCnt - LENGTH_802_11;
230 
231 	NdisMoveMemory(WEPKEY, pPayload, 3);	/*Get WEP IV */
232 
233 	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
234 	if (pGroupKey[KeyIdx].KeyLen == 0)
235 		return (FALSE);
236 
237 	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key,
238 		       pGroupKey[KeyIdx].KeyLen);
239 	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY,
240 		     pGroupKey[KeyIdx].KeyLen + 3);
241 	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4,
242 			payload_len - 4);
243 	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
244 	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);	/*Skip last 4 bytes(FCS). */
245 	crc32 ^= 0xffffffff;	/* complement */
246 
247 	if (crc32 != cpu2le32(trailfcs)) {
248 		DBGPRINT(RT_DEBUG_TRACE, ("WEP Data CRC Error!\n"));	/*CRC error. */
249 		return (FALSE);
250 	}
251 	return (TRUE);
252 }
253 
254 /*
255 	========================================================================
256 
257 	Routine	Description:
258 		The Stream Cipher Encryption Algorithm "struct rt_arcfour" initialize
259 
260 	Arguments:
261 	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
262 		pKey        Pointer to the WEP KEY
263 		KeyLen      Indicate the length fo the WEP KEY
264 
265 	Return Value:
266 	   None
267 
268 	IRQL = DISPATCH_LEVEL
269 
270 	Note:
271 
272 	========================================================================
273 */
ARCFOUR_INIT(struct rt_arcfourcontext * Ctx,u8 * pKey,u32 KeyLen)274 void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen)
275 {
276 	u8 t, u;
277 	u32 keyindex;
278 	u32 stateindex;
279 	u8 *state;
280 	u32 counter;
281 
282 	state = Ctx->STATE;
283 	Ctx->X = 0;
284 	Ctx->Y = 0;
285 	for (counter = 0; counter < 256; counter++)
286 		state[counter] = (u8)counter;
287 	keyindex = 0;
288 	stateindex = 0;
289 	for (counter = 0; counter < 256; counter++) {
290 		t = state[counter];
291 		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
292 		u = state[stateindex];
293 		state[stateindex] = t;
294 		state[counter] = u;
295 		if (++keyindex >= KeyLen)
296 			keyindex = 0;
297 	}
298 }
299 
300 /*
301 	========================================================================
302 
303 	Routine	Description:
304 		Get bytes from struct rt_arcfour CONTEXT (S-BOX)
305 
306 	Arguments:
307 	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
308 
309 	Return Value:
310 	   u8  - the value of the struct rt_arcfour CONTEXT (S-BOX)
311 
312 	Note:
313 
314 	========================================================================
315 */
ARCFOUR_BYTE(struct rt_arcfourcontext * Ctx)316 u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx)
317 {
318 	u32 x;
319 	u32 y;
320 	u8 sx, sy;
321 	u8 *state;
322 
323 	state = Ctx->STATE;
324 	x = (Ctx->X + 1) & 0xff;
325 	sx = state[x];
326 	y = (sx + Ctx->Y) & 0xff;
327 	sy = state[y];
328 	Ctx->X = x;
329 	Ctx->Y = y;
330 	state[y] = sx;
331 	state[x] = sy;
332 
333 	return (state[(sx + sy) & 0xff]);
334 
335 }
336 
337 /*
338 	========================================================================
339 
340 	Routine	Description:
341 		The Stream Cipher Decryption Algorithm
342 
343 	Arguments:
344 		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
345 		pDest			Pointer to the Destination
346 		pSrc        Pointer to the Source data
347 		Len         Indicate the length of the Source data
348 
349 	Return Value:
350 		None
351 
352 	Note:
353 
354 	========================================================================
355 */
ARCFOUR_DECRYPT(struct rt_arcfourcontext * Ctx,u8 * pDest,u8 * pSrc,u32 Len)356 void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
357 		     u8 *pDest, u8 *pSrc, u32 Len)
358 {
359 	u32 i;
360 
361 	for (i = 0; i < Len; i++)
362 		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
363 }
364 
365 /*
366 	========================================================================
367 
368 	Routine	Description:
369 		The Stream Cipher Encryption Algorithm
370 
371 	Arguments:
372 		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
373 		pDest			Pointer to the Destination
374 		pSrc        Pointer to the Source data
375 		Len         Indicate the length of the Source dta
376 
377 	Return Value:
378 		None
379 
380 	IRQL = DISPATCH_LEVEL
381 
382 	Note:
383 
384 	========================================================================
385 */
ARCFOUR_ENCRYPT(struct rt_arcfourcontext * Ctx,u8 * pDest,u8 * pSrc,u32 Len)386 void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
387 		     u8 *pDest, u8 *pSrc, u32 Len)
388 {
389 	u32 i;
390 
391 	for (i = 0; i < Len; i++)
392 		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
393 }
394 
395 /*
396 	========================================================================
397 
398 	Routine	Description:
399 		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
400 
401 	Arguments:
402 		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
403 		pDest			Pointer to the Destination
404 		pSrc        Pointer to the Source data
405 		Len         Indicate the length of the Source dta
406 
407 	========================================================================
408 */
409 
WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext * Ctx,u8 * pDest,u8 * pSrc,u32 Len)410 void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
411 			u8 *pDest, u8 *pSrc, u32 Len)
412 {
413 	u32 i;
414 	/*discard first 256 bytes */
415 	for (i = 0; i < 256; i++)
416 		ARCFOUR_BYTE(Ctx);
417 
418 	for (i = 0; i < Len; i++)
419 		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
420 }
421 
422 /*
423 	========================================================================
424 
425 	Routine	Description:
426 		Calculate a new FCS given the current FCS and the new data.
427 
428 	Arguments:
429 		Fcs	      the original FCS value
430 		Cp          pointer to the data which will be calculate the FCS
431 		Len         the length of the data
432 
433 	Return Value:
434 		u32 - FCS 32 bits
435 
436 	IRQL = DISPATCH_LEVEL
437 
438 	Note:
439 
440 	========================================================================
441 */
RTMP_CALC_FCS32(u32 Fcs,u8 * Cp,int Len)442 u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len)
443 {
444 	while (Len--)
445 		Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
446 
447 	return (Fcs);
448 }
449 
450 /*
451 	========================================================================
452 
453 	Routine	Description:
454 		Get last FCS and encrypt it to the destination
455 
456 	Arguments:
457 		pDest			Pointer to the Destination
458 
459 	Return Value:
460 		None
461 
462 	Note:
463 
464 	========================================================================
465 */
RTMPSetICV(struct rt_rtmp_adapter * pAd,u8 * pDest)466 void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest)
467 {
468 	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;	/* complement */
469 	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
470 
471 	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest,
472 			(u8 *)& pAd->PrivateInfo.FCSCRC32, 4);
473 }
474