GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / rt2860 / common / cmm_tkip.c
blob4881ef9ba022a98b02f119df537116bc6728ed96
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 cmm_tkip.c
30 Abstract:
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Paul Wu 02-25-02 Initial
38 #include "../rt_config.h"
40 /* Rotation functions on 32 bit values */
41 #define ROL32( A, n ) \
42 ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
43 #define ROR32( A, n ) ROL32( (A), 32-(n) )
45 u32 Tkip_Sbox_Lower[256] = {
46 0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54,
47 0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A,
48 0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B,
49 0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B,
50 0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F,
51 0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F,
52 0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5,
53 0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F,
54 0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB,
55 0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97,
56 0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED,
57 0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A,
58 0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94,
59 0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3,
60 0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04,
61 0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D,
62 0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39,
63 0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95,
64 0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83,
65 0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76,
66 0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4,
67 0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B,
68 0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0,
69 0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18,
70 0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51,
71 0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85,
72 0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12,
73 0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9,
74 0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7,
75 0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A,
76 0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8,
77 0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A
80 u32 Tkip_Sbox_Upper[256] = {
81 0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91,
82 0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC,
83 0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB,
84 0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B,
85 0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83,
86 0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A,
87 0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F,
88 0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA,
89 0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B,
90 0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13,
91 0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6,
92 0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85,
93 0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11,
94 0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B,
95 0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1,
96 0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF,
97 0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E,
98 0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6,
99 0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B,
100 0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD,
101 0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8,
102 0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2,
103 0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49,
104 0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10,
105 0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97,
106 0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F,
107 0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C,
108 0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27,
109 0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33,
110 0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5,
111 0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0,
112 0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C
115 /* */
116 /* Expanded IV for TKIP function. */
117 /* */
118 struct PACKED rt_tkip_iv {
119 union PACKED {
120 struct PACKED {
121 u8 rc0;
122 u8 rc1;
123 u8 rc2;
125 union PACKED {
126 struct PACKED {
127 u8 Rsvd:5;
128 u8 ExtIV:1;
129 u8 KeyID:2;
130 } field;
131 u8 Byte;
132 } CONTROL;
133 } field;
135 unsigned long word;
136 } IV16;
138 unsigned long IV32;
142 ========================================================================
144 Routine Description:
145 Convert from u8[] to unsigned long in a portable way
147 Arguments:
148 pMICKey pointer to MIC Key
150 Return Value:
151 None
153 Note:
155 ========================================================================
157 unsigned long RTMPTkipGetUInt32(u8 *pMICKey)
159 unsigned long res = 0;
160 int i;
162 for (i = 0; i < 4; i++) {
163 res |= (*pMICKey++) << (8 * i);
166 return res;
170 ========================================================================
172 Routine Description:
173 Convert from unsigned long to u8[] in a portable way
175 Arguments:
176 pDst pointer to destination for convert unsigned long to u8[]
177 val the value for convert
179 Return Value:
180 None
182 IRQL = DISPATCH_LEVEL
184 Note:
186 ========================================================================
188 void RTMPTkipPutUInt32(IN u8 *pDst, unsigned long val)
190 int i;
192 for (i = 0; i < 4; i++) {
193 *pDst++ = (u8)(val & 0xff);
194 val >>= 8;
199 ========================================================================
201 Routine Description:
202 Set the MIC Key.
204 Arguments:
205 pAd Pointer to our adapter
206 pMICKey pointer to MIC Key
208 Return Value:
209 None
211 IRQL = DISPATCH_LEVEL
213 Note:
215 ========================================================================
217 void RTMPTkipSetMICKey(struct rt_tkip_key_info *pTkip, u8 *pMICKey)
219 /* Set the key */
220 pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
221 pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
222 /* and reset the message */
223 pTkip->L = pTkip->K0;
224 pTkip->R = pTkip->K1;
225 pTkip->nBytesInM = 0;
226 pTkip->M = 0;
230 ========================================================================
232 Routine Description:
233 Calculate the MIC Value.
235 Arguments:
236 pAd Pointer to our adapter
237 uChar Append this uChar
239 Return Value:
240 None
242 IRQL = DISPATCH_LEVEL
244 Note:
246 ========================================================================
248 void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar)
250 /* Append the byte to our word-sized buffer */
251 pTkip->M |= (uChar << (8 * pTkip->nBytesInM));
252 pTkip->nBytesInM++;
253 /* Process the word if it is full. */
254 if (pTkip->nBytesInM >= 4) {
255 pTkip->L ^= pTkip->M;
256 pTkip->R ^= ROL32(pTkip->L, 17);
257 pTkip->L += pTkip->R;
258 pTkip->R ^=
259 ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->
260 L & 0x00ff00ff) << 8);
261 pTkip->L += pTkip->R;
262 pTkip->R ^= ROL32(pTkip->L, 3);
263 pTkip->L += pTkip->R;
264 pTkip->R ^= ROR32(pTkip->L, 2);
265 pTkip->L += pTkip->R;
266 /* Clear the buffer */
267 pTkip->M = 0;
268 pTkip->nBytesInM = 0;
273 ========================================================================
275 Routine Description:
276 Calculate the MIC Value.
278 Arguments:
279 pAd Pointer to our adapter
280 pSrc Pointer to source data for Calculate MIC Value
281 Len Indicate the length of the source data
283 Return Value:
284 None
286 IRQL = DISPATCH_LEVEL
288 Note:
290 ========================================================================
292 void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes)
294 /* This is simple */
295 while (nBytes > 0) {
296 RTMPTkipAppendByte(pTkip, *pSrc++);
297 nBytes--;
302 ========================================================================
304 Routine Description:
305 Get the MIC Value.
307 Arguments:
308 pAd Pointer to our adapter
310 Return Value:
311 None
313 IRQL = DISPATCH_LEVEL
315 Note:
316 the MIC Value is store in pAd->PrivateInfo.MIC
317 ========================================================================
319 void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip)
321 /* Append the minimum padding */
322 RTMPTkipAppendByte(pTkip, 0x5a);
323 RTMPTkipAppendByte(pTkip, 0);
324 RTMPTkipAppendByte(pTkip, 0);
325 RTMPTkipAppendByte(pTkip, 0);
326 RTMPTkipAppendByte(pTkip, 0);
327 /* and then zeroes until the length is a multiple of 4 */
328 while (pTkip->nBytesInM != 0) {
329 RTMPTkipAppendByte(pTkip, 0);
331 /* The appendByte function has already computed the result. */
332 RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
333 RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
337 ========================================================================
339 Routine Description:
340 Init Tkip function.
342 Arguments:
343 pAd Pointer to our adapter
344 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
345 KeyId TK Key ID
346 pTA Pointer to transmitter address
347 pMICKey pointer to MIC Key
349 Return Value:
350 None
352 IRQL = DISPATCH_LEVEL
354 Note:
356 ========================================================================
358 void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
359 u8 *pKey,
360 u8 KeyId,
361 u8 *pTA,
362 u8 *pMICKey,
363 u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32)
365 struct rt_tkip_iv tkipIv;
367 /* Prepare 8 bytes TKIP encapsulation for MPDU */
368 NdisZeroMemory(&tkipIv, sizeof(struct rt_tkip_iv));
369 tkipIv.IV16.field.rc0 = *(pTSC + 1);
370 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
371 tkipIv.IV16.field.rc2 = *pTSC;
372 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; /* 0: non-extended IV, 1: an extended IV */
373 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
374 /* tkipIv.IV32 = *(unsigned long *)(pTSC + 2); */
375 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); /* Copy IV */
377 *pIV16 = tkipIv.IV16.word;
378 *pIV32 = tkipIv.IV32;
382 ========================================================================
384 Routine Description:
385 Init MIC Value calculation function which include set MIC key &
386 calculate first 16 bytes (DA + SA + priority + 0)
388 Arguments:
389 pAd Pointer to our adapter
390 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
391 pDA Pointer to DA address
392 pSA Pointer to SA address
393 pMICKey pointer to MIC Key
395 Return Value:
396 None
398 Note:
400 ========================================================================
402 void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
403 u8 *pKey,
404 u8 *pDA,
405 u8 *pSA, u8 UserPriority, u8 *pMICKey)
407 unsigned long Priority = UserPriority;
409 /* Init MIC value calculation */
410 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
411 /* DA */
412 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
413 /* SA */
414 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
415 /* Priority + 3 bytes of 0 */
416 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (u8 *)& Priority, 4);
420 ========================================================================
422 Routine Description:
423 Compare MIC value of received MSDU
425 Arguments:
426 pAd Pointer to our adapter
427 pSrc Pointer to the received Plain text data
428 pDA Pointer to DA address
429 pSA Pointer to SA address
430 pMICKey pointer to MIC Key
431 Len the length of the received plain text data exclude MIC value
433 Return Value:
434 TRUE MIC value matched
435 FALSE MIC value mismatched
437 IRQL = DISPATCH_LEVEL
439 Note:
441 ========================================================================
443 BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
444 u8 *pSrc,
445 u8 *pDA,
446 u8 *pSA,
447 u8 *pMICKey,
448 u8 UserPriority, u32 Len)
450 u8 OldMic[8];
451 unsigned long Priority = UserPriority;
453 /* Init MIC value calculation */
454 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
455 /* DA */
456 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
457 /* SA */
458 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
459 /* Priority + 3 bytes of 0 */
460 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (u8 *)& Priority, 4);
462 /* Calculate MIC value from plain text data */
463 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
465 /* Get MIC valude from received frame */
466 NdisMoveMemory(OldMic, pSrc + Len, 8);
468 /* Get MIC value from decrypted plain data */
469 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
471 /* Move MIC value from MSDU, this steps should move to data path. */
472 /* Since the MIC value might cross MPDUs. */
473 if (!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) {
474 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); /*MIC error. */
476 return (FALSE);
478 return (TRUE);
482 ========================================================================
484 Routine Description:
485 Copy frame from waiting queue into relative ring buffer and set
486 appropriate ASIC register to kick hardware transmit function
488 Arguments:
489 pAd Pointer to our adapter
490 void * Pointer to Ndis Packet for MIC calculation
491 pEncap Pointer to LLC encap data
492 LenEncap Total encap length, might be 0 which indicates no encap
494 Return Value:
495 None
497 IRQL = DISPATCH_LEVEL
499 Note:
501 ========================================================================
503 void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
504 void *pPacket,
505 u8 *pEncap,
506 struct rt_cipher_key *pKey, u8 apidx)
508 struct rt_packet_info PacketInfo;
509 u8 *pSrcBufVA;
510 u32 SrcBufLen;
511 u8 *pSrc;
512 u8 UserPriority;
513 u8 vlan_offset = 0;
515 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
517 UserPriority = RTMP_GET_PACKET_UP(pPacket);
518 pSrc = pSrcBufVA;
520 /* determine if this is a vlan packet */
521 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
522 vlan_offset = 4;
525 RTMPInitMICEngine(pAd,
526 pKey->Key,
527 pSrc, pSrc + 6, UserPriority, pKey->TxMic);
530 if (pEncap != NULL) {
531 /* LLC encapsulation */
532 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
533 /* Protocol Type */
534 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset,
537 SrcBufLen -= (14 + vlan_offset);
538 pSrc += (14 + vlan_offset);
539 do {
540 if (SrcBufLen > 0) {
541 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
544 break; /* No need handle next packet */
546 } while (TRUE); /* End of copying payload */
548 /* Compute the final MIC Value */
549 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
552 /************************************************************/
553 /* tkip_sbox() */
554 /* Returns a 16 bit value from a 64K entry table. The Table */
555 /* is synthesized from two 256 entry byte wide tables. */
556 /************************************************************/
558 u32 tkip_sbox(u32 index)
560 u32 index_low;
561 u32 index_high;
562 u32 left, right;
564 index_low = (index % 256);
565 index_high = ((index >> 8) % 256);
567 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
568 right =
569 Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
571 return (left ^ right);
574 u32 rotr1(u32 a)
576 unsigned int b;
578 if ((a & 0x01) == 0x01) {
579 b = (a >> 1) | 0x8000;
580 } else {
581 b = (a >> 1) & 0x7fff;
583 b = b % 65536;
584 return b;
587 void RTMPTkipMixKey(u8 * key, u8 * ta, unsigned long pnl, /* Least significant 16 bits of PN */
588 unsigned long pnh, /* Most significant 32 bits of PN */
589 u8 * rc4key, u32 * p1k)
592 u32 tsc0;
593 u32 tsc1;
594 u32 tsc2;
596 u32 ppk0;
597 u32 ppk1;
598 u32 ppk2;
599 u32 ppk3;
600 u32 ppk4;
601 u32 ppk5;
603 int i;
604 int j;
606 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
607 tsc1 = (unsigned int)(pnh % 65536);
608 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
610 /* Phase 1, step 1 */
611 p1k[0] = tsc1;
612 p1k[1] = tsc0;
613 p1k[2] = (u32)(ta[0] + (ta[1] * 256));
614 p1k[3] = (u32)(ta[2] + (ta[3] * 256));
615 p1k[4] = (u32)(ta[4] + (ta[5] * 256));
617 /* Phase 1, step 2 */
618 for (i = 0; i < 8; i++) {
619 j = 2 * (i & 1);
620 p1k[0] =
621 (p1k[0] +
622 tkip_sbox((p1k[4] ^ ((256 * key[1 + j]) + key[j])) %
623 65536)) % 65536;
624 p1k[1] =
625 (p1k[1] +
626 tkip_sbox((p1k[0] ^ ((256 * key[5 + j]) + key[4 + j])) %
627 65536)) % 65536;
628 p1k[2] =
629 (p1k[2] +
630 tkip_sbox((p1k[1] ^ ((256 * key[9 + j]) + key[8 + j])) %
631 65536)) % 65536;
632 p1k[3] =
633 (p1k[3] +
634 tkip_sbox((p1k[2] ^ ((256 * key[13 + j]) + key[12 + j])) %
635 65536)) % 65536;
636 p1k[4] =
637 (p1k[4] +
638 tkip_sbox((p1k[3] ^ (((256 * key[1 + j]) + key[j]))) %
639 65536)) % 65536;
640 p1k[4] = (p1k[4] + i) % 65536;
643 /* Phase 2, Step 1 */
644 ppk0 = p1k[0];
645 ppk1 = p1k[1];
646 ppk2 = p1k[2];
647 ppk3 = p1k[3];
648 ppk4 = p1k[4];
649 ppk5 = (p1k[4] + tsc2) % 65536;
651 /* Phase2, Step 2 */
652 ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256 * key[1]) + key[0])) % 65536);
653 ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256 * key[3]) + key[2])) % 65536);
654 ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256 * key[5]) + key[4])) % 65536);
655 ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256 * key[7]) + key[6])) % 65536);
656 ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256 * key[9]) + key[8])) % 65536);
657 ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256 * key[11]) + key[10])) % 65536);
659 ppk0 = ppk0 + rotr1(ppk5 ^ ((256 * key[13]) + key[12]));
660 ppk1 = ppk1 + rotr1(ppk0 ^ ((256 * key[15]) + key[14]));
661 ppk2 = ppk2 + rotr1(ppk1);
662 ppk3 = ppk3 + rotr1(ppk2);
663 ppk4 = ppk4 + rotr1(ppk3);
664 ppk5 = ppk5 + rotr1(ppk4);
666 /* Phase 2, Step 3 */
667 /* Phase 2, Step 3 */
669 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
670 tsc1 = (unsigned int)(pnh % 65536);
671 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
673 rc4key[0] = (tsc2 >> 8) % 256;
674 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
675 rc4key[2] = tsc2 % 256;
676 rc4key[3] = ((ppk5 ^ ((256 * key[1]) + key[0])) >> 1) % 256;
678 rc4key[4] = ppk0 % 256;
679 rc4key[5] = (ppk0 >> 8) % 256;
681 rc4key[6] = ppk1 % 256;
682 rc4key[7] = (ppk1 >> 8) % 256;
684 rc4key[8] = ppk2 % 256;
685 rc4key[9] = (ppk2 >> 8) % 256;
687 rc4key[10] = ppk3 % 256;
688 rc4key[11] = (ppk3 >> 8) % 256;
690 rc4key[12] = ppk4 % 256;
691 rc4key[13] = (ppk4 >> 8) % 256;
693 rc4key[14] = ppk5 % 256;
694 rc4key[15] = (ppk5 >> 8) % 256;
697 /* */
698 /* TRUE: Success! */
699 /* FALSE: Decrypt Error! */
700 /* */
701 BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
702 u8 *pData,
703 unsigned long DataByteCnt,
704 u8 UserPriority, struct rt_cipher_key *pWpaKey)
706 u8 KeyID;
707 u32 HeaderLen;
708 u8 fc0;
709 u8 fc1;
710 u16 fc;
711 u32 frame_type;
712 u32 frame_subtype;
713 u32 from_ds;
714 u32 to_ds;
715 int a4_exists;
716 int qc_exists;
717 u16 duration;
718 u16 seq_control;
719 u16 qos_control;
720 u8 TA[MAC_ADDR_LEN];
721 u8 DA[MAC_ADDR_LEN];
722 u8 SA[MAC_ADDR_LEN];
723 u8 RC4Key[16];
724 u32 p1k[5]; /*for mix_key; */
725 unsigned long pnl; /* Least significant 16 bits of PN */
726 unsigned long pnh; /* Most significant 32 bits of PN */
727 u32 num_blocks;
728 u32 payload_remainder;
729 struct rt_arcfourcontext ArcFourContext;
730 u32 crc32 = 0;
731 u32 trailfcs = 0;
732 u8 MIC[8];
733 u8 TrailMIC[8];
735 fc0 = *pData;
736 fc1 = *(pData + 1);
738 fc = *((u16 *)pData);
740 frame_type = ((fc0 >> 2) & 0x03);
741 frame_subtype = ((fc0 >> 4) & 0x0f);
743 from_ds = (fc1 & 0x2) >> 1;
744 to_ds = (fc1 & 0x1);
746 a4_exists = (from_ds & to_ds);
747 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
748 (frame_subtype == 0x09) || /* Likely to change. */
749 (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
752 HeaderLen = 24;
753 if (a4_exists)
754 HeaderLen += 6;
756 KeyID = *((u8 *)(pData + HeaderLen + 3));
757 KeyID = KeyID >> 6;
759 if (pWpaKey[KeyID].KeyLen == 0) {
760 DBGPRINT(RT_DEBUG_TRACE,
761 ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n",
762 KeyID));
763 return FALSE;
766 duration = *((u16 *)(pData + 2));
768 seq_control = *((u16 *)(pData + 22));
770 if (qc_exists) {
771 if (a4_exists) {
772 qos_control = *((u16 *)(pData + 30));
773 } else {
774 qos_control = *((u16 *)(pData + 24));
778 if (to_ds == 0 && from_ds == 1) {
779 NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
780 NdisMoveMemory(SA, pData + 16, MAC_ADDR_LEN);
781 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN); /*BSSID */
782 } else if (to_ds == 0 && from_ds == 0) {
783 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
784 NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
785 NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
786 } else if (to_ds == 1 && from_ds == 0) {
787 NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
788 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
789 NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
790 } else if (to_ds == 1 && from_ds == 1) {
791 NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
792 NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
793 NdisMoveMemory(SA, pData + 22, MAC_ADDR_LEN);
796 num_blocks = (DataByteCnt - 16) / 16;
797 payload_remainder = (DataByteCnt - 16) % 16;
799 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
800 pnh = *((unsigned long *)(pData + HeaderLen + 4));
801 pnh = cpu2le32(pnh);
802 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
804 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
806 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen,
807 pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
808 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
809 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); /*Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). */
810 crc32 ^= 0xffffffff; /* complement */
812 if (crc32 != cpu2le32(trailfcs)) {
813 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); /*ICV error. */
815 return (FALSE);
818 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
819 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority,
820 pWpaKey[KeyID].RxMic);
821 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen,
822 DataByteCnt - HeaderLen - 8 - 12);
823 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
824 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
826 if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
827 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); /*MIC error. */
828 /*RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630 */
829 return (FALSE);
831 /*DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!\n"); */
832 return TRUE;