2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
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. *
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. *
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. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 Paul Wu 02-25-02 Initial
38 #include "../rt_config.h"
41 // Rotation functions on 32 bit values
42 #define ROL32( A, n ) \
43 ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
44 #define ROR32( A, n ) ROL32( (A), 32-(n) )
46 UINT Tkip_Sbox_Lower[256] =
48 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
49 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
50 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
51 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
52 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
53 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
54 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
55 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
56 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
57 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
58 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
59 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
60 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
61 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
62 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
63 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
64 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
65 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
66 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
67 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
68 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
69 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
70 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
71 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
72 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
73 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
74 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
75 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
76 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
77 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
78 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
79 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
82 UINT Tkip_Sbox_Upper[256] =
84 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
85 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
86 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
87 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
88 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
89 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
90 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
91 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
92 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
93 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
94 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
95 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
96 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
97 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
98 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
99 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
100 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
101 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
102 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
103 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
104 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
105 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
106 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
107 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
108 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
109 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
110 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
111 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
112 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
113 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
114 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
115 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
119 // Expanded IV for TKIP function.
121 typedef struct PACKED _IV_CONTROL_
153 } TKIP_IV, *PTKIP_IV;
157 ========================================================================
160 Convert from UCHAR[] to ULONG in a portable way
163 pMICKey pointer to MIC Key
170 ========================================================================
172 ULONG RTMPTkipGetUInt32(
178 for (i = 0; i < 4; i++)
180 res |= (*pMICKey++) << (8 * i);
187 ========================================================================
190 Convert from ULONG to UCHAR[] in a portable way
193 pDst pointer to destination for convert ULONG to UCHAR[]
194 val the value for convert
199 IRQL = DISPATCH_LEVEL
203 ========================================================================
205 VOID RTMPTkipPutUInt32(
211 for(i = 0; i < 4; i++)
213 *pDst++ = (UCHAR) (val & 0xff);
219 ========================================================================
225 pAd Pointer to our adapter
226 pMICKey pointer to MIC Key
231 IRQL = DISPATCH_LEVEL
235 ========================================================================
237 VOID RTMPTkipSetMICKey(
238 IN PTKIP_KEY_INFO pTkip,
242 pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
243 pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
244 // and reset the message
245 pTkip->L = pTkip->K0;
246 pTkip->R = pTkip->K1;
247 pTkip->nBytesInM = 0;
252 ========================================================================
255 Calculate the MIC Value.
258 pAd Pointer to our adapter
259 uChar Append this uChar
264 IRQL = DISPATCH_LEVEL
268 ========================================================================
270 VOID RTMPTkipAppendByte(
271 IN PTKIP_KEY_INFO pTkip,
274 // Append the byte to our word-sized buffer
275 pTkip->M |= (uChar << (8* pTkip->nBytesInM));
277 // Process the word if it is full.
278 if( pTkip->nBytesInM >= 4 )
280 pTkip->L ^= pTkip->M;
281 pTkip->R ^= ROL32( pTkip->L, 17 );
282 pTkip->L += pTkip->R;
283 pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
284 pTkip->L += pTkip->R;
285 pTkip->R ^= ROL32( pTkip->L, 3 );
286 pTkip->L += pTkip->R;
287 pTkip->R ^= ROR32( pTkip->L, 2 );
288 pTkip->L += pTkip->R;
291 pTkip->nBytesInM = 0;
296 ========================================================================
299 Calculate the MIC Value.
302 pAd Pointer to our adapter
303 pSrc Pointer to source data for Calculate MIC Value
304 Len Indicate the length of the source data
309 IRQL = DISPATCH_LEVEL
313 ========================================================================
316 IN PTKIP_KEY_INFO pTkip,
323 RTMPTkipAppendByte(pTkip, *pSrc++);
329 ========================================================================
335 pAd Pointer to our adapter
340 IRQL = DISPATCH_LEVEL
343 the MIC Value is store in pAd->PrivateInfo.MIC
344 ========================================================================
347 IN PTKIP_KEY_INFO pTkip)
349 // Append the minimum padding
350 RTMPTkipAppendByte(pTkip, 0x5a );
351 RTMPTkipAppendByte(pTkip, 0 );
352 RTMPTkipAppendByte(pTkip, 0 );
353 RTMPTkipAppendByte(pTkip, 0 );
354 RTMPTkipAppendByte(pTkip, 0 );
355 // and then zeroes until the length is a multiple of 4
356 while( pTkip->nBytesInM != 0 )
358 RTMPTkipAppendByte(pTkip, 0 );
360 // The appendByte function has already computed the result.
361 RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
362 RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
366 ========================================================================
372 pAd Pointer to our adapter
373 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
375 pTA Pointer to transmitter address
376 pMICKey pointer to MIC Key
381 IRQL = DISPATCH_LEVEL
385 ========================================================================
387 VOID RTMPInitTkipEngine(
388 IN PRTMP_ADAPTER pAd,
399 // Prepare 8 bytes TKIP encapsulation for MPDU
400 NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
401 tkipIv.IV16.field.rc0 = *(pTSC + 1);
402 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
403 tkipIv.IV16.field.rc2 = *pTSC;
404 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
405 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
406 // tkipIv.IV32 = *(PULONG)(pTSC + 2);
407 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
409 *pIV16 = tkipIv.IV16.word;
410 *pIV32 = tkipIv.IV32;
414 ========================================================================
417 Init MIC Value calculation function which include set MIC key &
418 calculate first 16 bytes (DA + SA + priority + 0)
421 pAd Pointer to our adapter
422 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
423 pDA Pointer to DA address
424 pSA Pointer to SA address
425 pMICKey pointer to MIC Key
432 ========================================================================
434 VOID RTMPInitMICEngine(
435 IN PRTMP_ADAPTER pAd,
439 IN UCHAR UserPriority,
442 ULONG Priority = UserPriority;
444 // Init MIC value calculation
445 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
447 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
449 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
450 // Priority + 3 bytes of 0
451 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
455 ========================================================================
458 Compare MIC value of received MSDU
461 pAd Pointer to our adapter
462 pSrc Pointer to the received Plain text data
463 pDA Pointer to DA address
464 pSA Pointer to SA address
465 pMICKey pointer to MIC Key
466 Len the length of the received plain text data exclude MIC value
469 TRUE MIC value matched
470 FALSE MIC value mismatched
472 IRQL = DISPATCH_LEVEL
476 ========================================================================
478 BOOLEAN RTMPTkipCompareMICValue(
479 IN PRTMP_ADAPTER pAd,
484 IN UCHAR UserPriority,
488 ULONG Priority = UserPriority;
490 // Init MIC value calculation
491 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
493 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
495 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
496 // Priority + 3 bytes of 0
497 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
499 // Calculate MIC value from plain text data
500 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
502 // Get MIC valude from received frame
503 NdisMoveMemory(OldMic, pSrc + Len, 8);
505 // Get MIC value from decrypted plain data
506 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
508 // Move MIC value from MSDU, this steps should move to data path.
509 // Since the MIC value might cross MPDUs.
510 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
512 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
521 ========================================================================
524 Compare MIC value of received MSDU
527 pAd Pointer to our adapter
529 pSrc Pointer to the received Plain text data
530 pDA Pointer to DA address
531 pSA Pointer to SA address
532 pMICKey pointer to MIC Key
533 Len the length of the received plain text data exclude MIC value
536 TRUE MIC value matched
537 FALSE MIC value mismatched
539 IRQL = DISPATCH_LEVEL
543 ========================================================================
545 BOOLEAN RTMPTkipCompareMICValueWithLLC(
546 IN PRTMP_ADAPTER pAd,
557 // Init MIC value calculation
558 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
560 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
562 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
563 // Priority + 3 bytes of 0
564 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
566 // Start with LLC header
567 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
569 // Calculate MIC value from plain text data
570 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
572 // Get MIC valude from received frame
573 NdisMoveMemory(OldMic, pSrc + Len, 8);
575 // Get MIC value from decrypted plain data
576 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
578 // Move MIC value from MSDU, this steps should move to data path.
579 // Since the MIC value might cross MPDUs.
580 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
582 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
590 ========================================================================
593 Copy frame from waiting queue into relative ring buffer and set
594 appropriate ASIC register to kick hardware transmit function
597 pAd Pointer to our adapter
598 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
599 pEncap Pointer to LLC encap data
600 LenEncap Total encap length, might be 0 which indicates no encap
605 IRQL = DISPATCH_LEVEL
609 ========================================================================
611 VOID RTMPCalculateMICValue(
612 IN PRTMP_ADAPTER pAd,
613 IN PNDIS_PACKET pPacket,
618 PACKET_INFO PacketInfo;
623 UCHAR vlan_offset = 0;
625 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
627 UserPriority = RTMP_GET_PACKET_UP(pPacket);
630 // determine if this is a vlan packet
631 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
634 #ifdef CONFIG_STA_SUPPORT
635 #endif // CONFIG_STA_SUPPORT //
650 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
652 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
654 SrcBufLen -= (14 + vlan_offset);
655 pSrc += (14 + vlan_offset);
660 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
663 break; // No need handle next packet
665 } while (TRUE); // End of copying payload
667 // Compute the final MIC Value
668 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
672 /************************************************************/
674 /* Returns a 16 bit value from a 64K entry table. The Table */
675 /* is synthesized from two 256 entry byte wide tables. */
676 /************************************************************/
678 UINT tkip_sbox(UINT index)
684 index_low = (index % 256);
685 index_high = ((index >> 8) % 256);
687 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
688 right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
690 return (left ^ right);
697 if ((a & 0x01) == 0x01)
699 b = (a >> 1) | 0x8000;
703 b = (a >> 1) & 0x7fff;
712 ULONG pnl, /* Least significant 16 bits of PN */
713 ULONG pnh, /* Most significant 32 bits of PN */
732 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
733 tsc1 = (unsigned int)(pnh % 65536);
734 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
736 /* Phase 1, step 1 */
739 p1k[2] = (UINT)(ta[0] + (ta[1]*256));
740 p1k[3] = (UINT)(ta[2] + (ta[3]*256));
741 p1k[4] = (UINT)(ta[4] + (ta[5]*256));
743 /* Phase 1, step 2 */
747 p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
748 p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
749 p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
750 p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
751 p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
752 p1k[4] = (p1k[4] + i) % 65536;
755 /* Phase 2, Step 1 */
761 ppk5 = (p1k[4] + tsc2) % 65536;
764 ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
765 ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
766 ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
767 ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
768 ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
769 ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
771 ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
772 ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
773 ppk2 = ppk2 + rotr1(ppk1);
774 ppk3 = ppk3 + rotr1(ppk2);
775 ppk4 = ppk4 + rotr1(ppk3);
776 ppk5 = ppk5 + rotr1(ppk4);
778 /* Phase 2, Step 3 */
779 /* Phase 2, Step 3 */
781 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
782 tsc1 = (unsigned int)(pnh % 65536);
783 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
785 rc4key[0] = (tsc2 >> 8) % 256;
786 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
787 rc4key[2] = tsc2 % 256;
788 rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
790 rc4key[4] = ppk0 % 256;
791 rc4key[5] = (ppk0 >> 8) % 256;
793 rc4key[6] = ppk1 % 256;
794 rc4key[7] = (ppk1 >> 8) % 256;
796 rc4key[8] = ppk2 % 256;
797 rc4key[9] = (ppk2 >> 8) % 256;
799 rc4key[10] = ppk3 % 256;
800 rc4key[11] = (ppk3 >> 8) % 256;
802 rc4key[12] = ppk4 % 256;
803 rc4key[13] = (ppk4 >> 8) % 256;
805 rc4key[14] = ppk5 % 256;
806 rc4key[15] = (ppk5 >> 8) % 256;
812 // FALSE: Decrypt Error!
814 BOOLEAN RTMPSoftDecryptTKIP(
815 IN PRTMP_ADAPTER pAd,
817 IN ULONG DataByteCnt,
818 IN UCHAR UserPriority,
819 IN PCIPHER_KEY pWpaKey)
835 UCHAR TA[MAC_ADDR_LEN];
836 UCHAR DA[MAC_ADDR_LEN];
837 UCHAR SA[MAC_ADDR_LEN];
839 UINT p1k[5]; //for mix_key;
840 ULONG pnl;/* Least significant 16 bits of PN */
841 ULONG pnh;/* Most significant 32 bits of PN */
843 UINT payload_remainder;
844 ARCFOURCONTEXT ArcFourContext;
851 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
857 fc = *((PUSHORT)pData);
859 frame_type = ((fc0 >> 2) & 0x03);
860 frame_subtype = ((fc0 >> 4) & 0x0f);
862 from_ds = (fc1 & 0x2) >> 1;
865 a4_exists = (from_ds & to_ds);
866 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
867 (frame_subtype == 0x09) || /* Likely to change. */
868 (frame_subtype == 0x0a) ||
869 (frame_subtype == 0x0b)
876 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
879 if (pWpaKey[KeyID].KeyLen == 0)
881 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
885 duration = *((PUSHORT)(pData+2));
887 seq_control = *((PUSHORT)(pData+22));
893 qos_control = *((PUSHORT)(pData+30));
897 qos_control = *((PUSHORT)(pData+24));
901 if (to_ds == 0 && from_ds == 1)
903 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
904 NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
905 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
907 else if (to_ds == 0 && from_ds == 0 )
909 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
910 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
911 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
913 else if (to_ds == 1 && from_ds == 0)
915 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
916 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
917 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
919 else if (to_ds == 1 && from_ds == 1)
921 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
922 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
923 NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
926 num_blocks = (DataByteCnt - 16) / 16;
927 payload_remainder = (DataByteCnt - 16) % 16;
929 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
930 pnh = *((PULONG)(pData + HeaderLen + 4));
932 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
934 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
936 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
937 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
938 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
939 crc32 ^= 0xffffffff; /* complement */
941 if(crc32 != cpu2le32(trailfcs))
943 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
948 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
949 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
950 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
951 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
952 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
954 if (!NdisEqualMemory(MIC, TrailMIC, 8))
956 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
957 //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
962 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
964 //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");