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