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