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"
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 UINT Tkip_Sbox_Lower[256] =
47 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
48 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
49 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
50 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
51 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
52 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
53 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
54 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
55 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
56 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
57 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
58 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
59 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
60 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
61 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
62 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
63 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
64 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
65 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
66 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
67 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
68 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
69 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
70 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
71 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
72 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
73 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
74 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
75 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
76 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
77 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
78 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
81 UINT Tkip_Sbox_Upper[256] =
83 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
84 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
85 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
86 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
87 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
88 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
89 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
90 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
91 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
92 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
93 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
94 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
95 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
96 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
97 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
98 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
99 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
100 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
101 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
102 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
103 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
104 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
105 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
106 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
107 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
108 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
109 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
110 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
111 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
112 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
113 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
114 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
117 /*****************************/
118 /******** SBOX Table *********/
119 /*****************************/
121 UCHAR SboxTable[256] =
123 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
124 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
125 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
126 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
127 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
128 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
129 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
130 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
131 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
132 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
133 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
134 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
135 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
136 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
137 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
138 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
139 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
140 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
141 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
142 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
143 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
144 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
145 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
146 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
147 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
148 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
149 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
150 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
151 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
152 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
153 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
154 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
186 // Expanded IV for TKIP function.
188 typedef struct PACKED _IV_CONTROL_
214 } TKIP_IV, *PTKIP_IV;
218 ========================================================================
221 Convert from UCHAR[] to ULONG in a portable way
224 pMICKey pointer to MIC Key
231 ========================================================================
233 ULONG RTMPTkipGetUInt32(
239 for (i = 0; i < 4; i++)
241 res |= (*pMICKey++) << (8 * i);
248 ========================================================================
251 Convert from ULONG to UCHAR[] in a portable way
254 pDst pointer to destination for convert ULONG to UCHAR[]
255 val the value for convert
260 IRQL = DISPATCH_LEVEL
264 ========================================================================
266 VOID RTMPTkipPutUInt32(
272 for(i = 0; i < 4; i++)
274 *pDst++ = (UCHAR) (val & 0xff);
280 ========================================================================
286 pAd Pointer to our adapter
287 pMICKey pointer to MIC Key
292 IRQL = DISPATCH_LEVEL
296 ========================================================================
298 VOID RTMPTkipSetMICKey(
299 IN PTKIP_KEY_INFO pTkip,
303 pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
304 pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
305 // and reset the message
306 pTkip->L = pTkip->K0;
307 pTkip->R = pTkip->K1;
308 pTkip->nBytesInM = 0;
313 ========================================================================
316 Calculate the MIC Value.
319 pAd Pointer to our adapter
320 uChar Append this uChar
325 IRQL = DISPATCH_LEVEL
329 ========================================================================
331 VOID RTMPTkipAppendByte(
332 IN PTKIP_KEY_INFO pTkip,
335 // Append the byte to our word-sized buffer
336 pTkip->M |= (uChar << (8* pTkip->nBytesInM));
338 // Process the word if it is full.
339 if( pTkip->nBytesInM >= 4 )
341 pTkip->L ^= pTkip->M;
342 pTkip->R ^= ROL32( pTkip->L, 17 );
343 pTkip->L += pTkip->R;
344 pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
345 pTkip->L += pTkip->R;
346 pTkip->R ^= ROL32( pTkip->L, 3 );
347 pTkip->L += pTkip->R;
348 pTkip->R ^= ROR32( pTkip->L, 2 );
349 pTkip->L += pTkip->R;
352 pTkip->nBytesInM = 0;
357 ========================================================================
360 Calculate the MIC Value.
363 pAd Pointer to our adapter
364 pSrc Pointer to source data for Calculate MIC Value
365 Len Indicate the length of the source data
370 IRQL = DISPATCH_LEVEL
374 ========================================================================
377 IN PTKIP_KEY_INFO pTkip,
384 RTMPTkipAppendByte(pTkip, *pSrc++);
390 ========================================================================
396 pAd Pointer to our adapter
401 IRQL = DISPATCH_LEVEL
404 the MIC Value is store in pAd->PrivateInfo.MIC
405 ========================================================================
408 IN PTKIP_KEY_INFO pTkip)
410 // Append the minimum padding
411 RTMPTkipAppendByte(pTkip, 0x5a );
412 RTMPTkipAppendByte(pTkip, 0 );
413 RTMPTkipAppendByte(pTkip, 0 );
414 RTMPTkipAppendByte(pTkip, 0 );
415 RTMPTkipAppendByte(pTkip, 0 );
416 // and then zeroes until the length is a multiple of 4
417 while( pTkip->nBytesInM != 0 )
419 RTMPTkipAppendByte(pTkip, 0 );
421 // The appendByte function has already computed the result.
422 RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
423 RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
427 ========================================================================
433 pAd Pointer to our adapter
434 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
436 pTA Pointer to transmitter address
437 pMICKey pointer to MIC Key
442 IRQL = DISPATCH_LEVEL
446 ========================================================================
448 VOID RTMPInitTkipEngine(
449 IN PRTMP_ADAPTER pAd,
460 // Prepare 8 bytes TKIP encapsulation for MPDU
461 NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
462 tkipIv.IV16.field.rc0 = *(pTSC + 1);
463 tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
464 tkipIv.IV16.field.rc2 = *pTSC;
465 tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
466 tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
467 // tkipIv.IV32 = *(PULONG)(pTSC + 2);
468 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
470 *pIV16 = tkipIv.IV16.word;
471 *pIV32 = tkipIv.IV32;
475 ========================================================================
478 Init MIC Value calculation function which include set MIC key &
479 calculate first 16 bytes (DA + SA + priority + 0)
482 pAd Pointer to our adapter
483 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
484 pDA Pointer to DA address
485 pSA Pointer to SA address
486 pMICKey pointer to MIC Key
493 ========================================================================
495 VOID RTMPInitMICEngine(
496 IN PRTMP_ADAPTER pAd,
500 IN UCHAR UserPriority,
503 ULONG Priority = UserPriority;
505 // Init MIC value calculation
506 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
508 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
510 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
511 // Priority + 3 bytes of 0
512 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
516 ========================================================================
519 Compare MIC value of received MSDU
522 pAd Pointer to our adapter
523 pSrc Pointer to the received Plain text data
524 pDA Pointer to DA address
525 pSA Pointer to SA address
526 pMICKey pointer to MIC Key
527 Len the length of the received plain text data exclude MIC value
530 TRUE MIC value matched
531 FALSE MIC value mismatched
533 IRQL = DISPATCH_LEVEL
537 ========================================================================
539 BOOLEAN RTMPTkipCompareMICValue(
540 IN PRTMP_ADAPTER pAd,
545 IN UCHAR UserPriority,
549 ULONG Priority = UserPriority;
551 // Init MIC value calculation
552 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
554 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
556 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
557 // Priority + 3 bytes of 0
558 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
560 // Calculate MIC value from plain text data
561 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
563 // Get MIC valude from received frame
564 NdisMoveMemory(OldMic, pSrc + Len, 8);
566 // Get MIC value from decrypted plain data
567 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
569 // Move MIC value from MSDU, this steps should move to data path.
570 // Since the MIC value might cross MPDUs.
571 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
573 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
582 ========================================================================
585 Compare MIC value of received MSDU
588 pAd Pointer to our adapter
590 pSrc Pointer to the received Plain text data
591 pDA Pointer to DA address
592 pSA Pointer to SA address
593 pMICKey pointer to MIC Key
594 Len the length of the received plain text data exclude MIC value
597 TRUE MIC value matched
598 FALSE MIC value mismatched
600 IRQL = DISPATCH_LEVEL
604 ========================================================================
606 BOOLEAN RTMPTkipCompareMICValueWithLLC(
607 IN PRTMP_ADAPTER pAd,
618 // Init MIC value calculation
619 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
621 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
623 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
624 // Priority + 3 bytes of 0
625 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
627 // Start with LLC header
628 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
630 // Calculate MIC value from plain text data
631 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
633 // Get MIC valude from received frame
634 NdisMoveMemory(OldMic, pSrc + Len, 8);
636 // Get MIC value from decrypted plain data
637 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
639 // Move MIC value from MSDU, this steps should move to data path.
640 // Since the MIC value might cross MPDUs.
641 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
643 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
651 ========================================================================
654 Copy frame from waiting queue into relative ring buffer and set
655 appropriate ASIC register to kick hardware transmit function
658 pAd Pointer to our adapter
659 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
660 pEncap Pointer to LLC encap data
661 LenEncap Total encap length, might be 0 which indicates no encap
666 IRQL = DISPATCH_LEVEL
670 ========================================================================
672 VOID RTMPCalculateMICValue(
673 IN PRTMP_ADAPTER pAd,
674 IN PNDIS_PACKET pPacket,
679 PACKET_INFO PacketInfo;
684 UCHAR vlan_offset = 0;
686 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
688 UserPriority = RTMP_GET_PACKET_UP(pPacket);
691 // determine if this is a vlan packet
692 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
708 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
710 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
712 SrcBufLen -= (14 + vlan_offset);
713 pSrc += (14 + vlan_offset);
718 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
721 break; // No need handle next packet
723 } while (TRUE); // End of copying payload
725 // Compute the final MIC Value
726 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
730 /************************************************************/
732 /* Returns a 16 bit value from a 64K entry table. The Table */
733 /* is synthesized from two 256 entry byte wide tables. */
734 /************************************************************/
736 UINT tkip_sbox(UINT index)
742 index_low = (index % 256);
743 index_high = ((index >> 8) % 256);
745 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
746 right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
748 return (left ^ right);
755 if ((a & 0x01) == 0x01)
757 b = (a >> 1) | 0x8000;
761 b = (a >> 1) & 0x7fff;
770 ULONG pnl, /* Least significant 16 bits of PN */
771 ULONG pnh, /* Most significant 32 bits of PN */
790 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
791 tsc1 = (unsigned int)(pnh % 65536);
792 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
794 /* Phase 1, step 1 */
797 p1k[2] = (UINT)(ta[0] + (ta[1]*256));
798 p1k[3] = (UINT)(ta[2] + (ta[3]*256));
799 p1k[4] = (UINT)(ta[4] + (ta[5]*256));
801 /* Phase 1, step 2 */
805 p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
806 p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
807 p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
808 p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
809 p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
810 p1k[4] = (p1k[4] + i) % 65536;
813 /* Phase 2, Step 1 */
819 ppk5 = (p1k[4] + tsc2) % 65536;
822 ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
823 ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
824 ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
825 ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
826 ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
827 ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
829 ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
830 ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
831 ppk2 = ppk2 + rotr1(ppk1);
832 ppk3 = ppk3 + rotr1(ppk2);
833 ppk4 = ppk4 + rotr1(ppk3);
834 ppk5 = ppk5 + rotr1(ppk4);
836 /* Phase 2, Step 3 */
837 /* Phase 2, Step 3 */
839 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
840 tsc1 = (unsigned int)(pnh % 65536);
841 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
843 rc4key[0] = (tsc2 >> 8) % 256;
844 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
845 rc4key[2] = tsc2 % 256;
846 rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
848 rc4key[4] = ppk0 % 256;
849 rc4key[5] = (ppk0 >> 8) % 256;
851 rc4key[6] = ppk1 % 256;
852 rc4key[7] = (ppk1 >> 8) % 256;
854 rc4key[8] = ppk2 % 256;
855 rc4key[9] = (ppk2 >> 8) % 256;
857 rc4key[10] = ppk3 % 256;
858 rc4key[11] = (ppk3 >> 8) % 256;
860 rc4key[12] = ppk4 % 256;
861 rc4key[13] = (ppk4 >> 8) % 256;
863 rc4key[14] = ppk5 % 256;
864 rc4key[15] = (ppk5 >> 8) % 256;
868 /************************************************/
869 /* construct_mic_header1() */
870 /* Builds the first MIC header block from */
872 /************************************************/
874 void construct_mic_header1(
875 unsigned char *mic_header1,
879 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
880 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
881 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
882 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
883 mic_header1[4] = mpdu[4]; /* A1 */
884 mic_header1[5] = mpdu[5];
885 mic_header1[6] = mpdu[6];
886 mic_header1[7] = mpdu[7];
887 mic_header1[8] = mpdu[8];
888 mic_header1[9] = mpdu[9];
889 mic_header1[10] = mpdu[10]; /* A2 */
890 mic_header1[11] = mpdu[11];
891 mic_header1[12] = mpdu[12];
892 mic_header1[13] = mpdu[13];
893 mic_header1[14] = mpdu[14];
894 mic_header1[15] = mpdu[15];
897 /************************************************/
898 /* construct_mic_header2() */
899 /* Builds the last MIC header block from */
901 /************************************************/
903 void construct_mic_header2(
904 unsigned char *mic_header2,
911 for (i = 0; i<16; i++) mic_header2[i]=0x00;
913 mic_header2[0] = mpdu[16]; /* A3 */
914 mic_header2[1] = mpdu[17];
915 mic_header2[2] = mpdu[18];
916 mic_header2[3] = mpdu[19];
917 mic_header2[4] = mpdu[20];
918 mic_header2[5] = mpdu[21];
920 // In Sequence Control field, mute sequence numer bits (12-bit)
921 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
922 mic_header2[7] = 0x00; /* mpdu[23]; */
924 if ((!qc_exists) & a4_exists)
926 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
930 if (qc_exists && (!a4_exists))
932 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
933 mic_header2[9] = mpdu[25] & 0x00;
936 if (qc_exists && a4_exists)
938 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
940 mic_header2[14] = mpdu[30] & 0x0f;
941 mic_header2[15] = mpdu[31] & 0x00;
946 /************************************************/
947 /* construct_mic_iv() */
948 /* Builds the MIC IV from header fields and PN */
949 /************************************************/
951 void construct_mic_iv(
952 unsigned char *mic_iv,
956 unsigned int payload_length,
957 unsigned char *pn_vector)
962 if (qc_exists && a4_exists)
963 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
964 if (qc_exists && !a4_exists)
965 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
968 for (i = 2; i < 8; i++)
969 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
970 #ifdef CONSISTENT_PN_ORDER
971 for (i = 8; i < 14; i++)
972 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
974 for (i = 8; i < 14; i++)
975 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
977 i = (payload_length / 256);
978 i = (payload_length % 256);
979 mic_iv[14] = (unsigned char) (payload_length / 256);
980 mic_iv[15] = (unsigned char) (payload_length % 256);
986 /************************************/
988 /* A 128 bit, bitwise exclusive or */
989 /************************************/
991 void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
996 out[i] = ina[i] ^ inb[i];
1001 void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
1005 unsigned char intermediatea[16];
1006 unsigned char intermediateb[16];
1007 unsigned char round_key[16];
1009 for(i=0; i<16; i++) round_key[i] = key[i];
1011 for (round = 0; round < 11; round++)
1015 xor_128(round_key, data, ciphertext);
1016 next_key(round_key, round);
1018 else if (round == 10)
1020 byte_sub(ciphertext, intermediatea);
1021 shift_row(intermediatea, intermediateb);
1022 xor_128(intermediateb, round_key, ciphertext);
1026 byte_sub(ciphertext, intermediatea);
1027 shift_row(intermediatea, intermediateb);
1028 mix_column(&intermediateb[0], &intermediatea[0]);
1029 mix_column(&intermediateb[4], &intermediatea[4]);
1030 mix_column(&intermediateb[8], &intermediatea[8]);
1031 mix_column(&intermediateb[12], &intermediatea[12]);
1032 xor_128(intermediatea, round_key, ciphertext);
1033 next_key(round_key, round);
1039 void construct_ctr_preload(
1040 unsigned char *ctr_preload,
1043 unsigned char *mpdu,
1044 unsigned char *pn_vector,
1049 for (i=0; i<16; i++) ctr_preload[i] = 0x00;
1052 ctr_preload[0] = 0x01; /* flag */
1053 if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1054 if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
1056 for (i = 2; i < 8; i++)
1057 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1058 #ifdef CONSISTENT_PN_ORDER
1059 for (i = 8; i < 14; i++)
1060 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1062 for (i = 8; i < 14; i++)
1063 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1065 ctr_preload[14] = (unsigned char) (c / 256); // Ctr
1066 ctr_preload[15] = (unsigned char) (c % 256);
1073 // FALSE: Decrypt Error!
1075 BOOLEAN RTMPSoftDecryptTKIP(
1076 IN PRTMP_ADAPTER pAd,
1078 IN ULONG DataByteCnt,
1079 IN UCHAR UserPriority,
1080 IN PCIPHER_KEY pWpaKey)
1096 UCHAR TA[MAC_ADDR_LEN];
1097 UCHAR DA[MAC_ADDR_LEN];
1098 UCHAR SA[MAC_ADDR_LEN];
1100 UINT p1k[5]; //for mix_key;
1101 ULONG pnl;/* Least significant 16 bits of PN */
1102 ULONG pnh;/* Most significant 32 bits of PN */
1104 UINT payload_remainder;
1105 ARCFOURCONTEXT ArcFourContext;
1114 fc = *((PUSHORT)pData);
1116 frame_type = ((fc0 >> 2) & 0x03);
1117 frame_subtype = ((fc0 >> 4) & 0x0f);
1119 from_ds = (fc1 & 0x2) >> 1;
1120 to_ds = (fc1 & 0x1);
1122 a4_exists = (from_ds & to_ds);
1123 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1124 (frame_subtype == 0x09) || /* Likely to change. */
1125 (frame_subtype == 0x0a) ||
1126 (frame_subtype == 0x0b)
1133 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1136 if (pWpaKey[KeyID].KeyLen == 0)
1138 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1142 duration = *((PUSHORT)(pData+2));
1144 seq_control = *((PUSHORT)(pData+22));
1150 qos_control = *((PUSHORT)(pData+30));
1154 qos_control = *((PUSHORT)(pData+24));
1158 if (to_ds == 0 && from_ds == 1)
1160 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1161 NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
1162 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
1164 else if (to_ds == 0 && from_ds == 0 )
1166 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1167 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1168 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1170 else if (to_ds == 1 && from_ds == 0)
1172 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1173 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1174 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1176 else if (to_ds == 1 && from_ds == 1)
1178 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1179 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1180 NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
1183 num_blocks = (DataByteCnt - 16) / 16;
1184 payload_remainder = (DataByteCnt - 16) % 16;
1186 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
1187 pnh = *((PULONG)(pData + HeaderLen + 4));
1188 pnh = cpu2le32(pnh);
1189 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
1191 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
1193 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
1194 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
1195 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
1196 crc32 ^= 0xffffffff; /* complement */
1198 if(crc32 != cpu2le32(trailfcs))
1200 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
1205 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
1206 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
1207 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
1208 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
1209 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
1211 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1213 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
1214 //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
1218 //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
1225 BOOLEAN RTMPSoftDecryptAES(
1226 IN PRTMP_ADAPTER pAd,
1228 IN ULONG DataByteCnt,
1229 IN PCIPHER_KEY pWpaKey)
1236 UINT payload_remainder;
1249 UCHAR ctr_preload[16];
1250 UCHAR chain_buffer[16];
1251 UCHAR padded_buffer[16];
1253 UCHAR mic_header1[16];
1254 UCHAR mic_header2[16];
1261 fc = *((PUSHORT)pData);
1263 frame_type = ((fc0 >> 2) & 0x03);
1264 frame_subtype = ((fc0 >> 4) & 0x0f);
1266 from_ds = (fc1 & 0x2) >> 1;
1267 to_ds = (fc1 & 0x1);
1269 a4_exists = (from_ds & to_ds);
1270 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1271 (frame_subtype == 0x09) || /* Likely to change. */
1272 (frame_subtype == 0x0a) ||
1273 (frame_subtype == 0x0b)
1280 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1283 if (pWpaKey[KeyID].KeyLen == 0)
1285 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1289 PN[0] = *(pData+ HeaderLen);
1290 PN[1] = *(pData+ HeaderLen + 1);
1291 PN[2] = *(pData+ HeaderLen + 4);
1292 PN[3] = *(pData+ HeaderLen + 5);
1293 PN[4] = *(pData+ HeaderLen + 6);
1294 PN[5] = *(pData+ HeaderLen + 7);
1296 payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
1297 payload_remainder = (payload_len) % 16;
1298 num_blocks = (payload_len) / 16;
1302 // Find start of payload
1303 payload_index = HeaderLen + 8; //IV+EIV
1305 for (i=0; i< num_blocks; i++)
1307 construct_ctr_preload(ctr_preload,
1314 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1316 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1317 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
1318 payload_index += 16;
1322 // If there is a short final block, then pad it
1323 // encrypt it and copy the unpadded part back
1325 if (payload_remainder > 0)
1327 construct_ctr_preload(ctr_preload,
1334 NdisZeroMemory(padded_buffer, 16);
1335 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1337 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1339 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1340 NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
1341 payload_index += payload_remainder;
1347 construct_ctr_preload(ctr_preload,
1353 NdisZeroMemory(padded_buffer, 16);
1354 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
1356 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1358 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1360 NdisMoveMemory(TrailMIC, chain_buffer, 8);
1366 //Force the protected frame bit on
1367 *(pData + 1) = *(pData + 1) | 0x40;
1369 // Find start of payload
1370 // Because the CCMP header has been removed
1371 payload_index = HeaderLen;
1381 construct_mic_header1(
1386 construct_mic_header2(
1392 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
1393 bitwise_xor(aes_out, mic_header1, chain_buffer);
1394 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1395 bitwise_xor(aes_out, mic_header2, chain_buffer);
1396 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1398 // iterate through each 16 byte payload block
1399 for (i = 0; i < num_blocks; i++)
1401 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1402 payload_index += 16;
1403 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1406 // Add on the final payload block if it needs padding
1407 if (payload_remainder > 0)
1409 NdisZeroMemory(padded_buffer, 16);
1410 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1412 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1413 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1416 // aes_out contains padded mic, discard most significant
1417 // 8 bytes to generate 64 bit MIC
1418 for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
1420 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1422 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
1429 /****************************************/
1431 /* Performs a 128 bit AES encrypt with */
1433 /****************************************/
1443 out[i] = a[i] ^ b[i];
1453 UCHAR rcon_table[12] =
1455 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1456 0x1b, 0x36, 0x36, 0x36
1459 sbox_key[0] = RTMPCkipSbox(key[13]);
1460 sbox_key[1] = RTMPCkipSbox(key[14]);
1461 sbox_key[2] = RTMPCkipSbox(key[15]);
1462 sbox_key[3] = RTMPCkipSbox(key[12]);
1464 rcon = rcon_table[round];
1466 xor_32(&key[0], sbox_key, &key[0]);
1467 key[0] = key[0] ^ rcon;
1469 xor_32(&key[4], &key[0], &key[4]);
1470 xor_32(&key[8], &key[4], &key[8]);
1471 xor_32(&key[12], &key[8], &key[12]);
1483 out[i] = a[i] ^ b[i];
1493 for (i=0; i< 16; i++)
1495 out[i] = RTMPCkipSbox(in[i]);
1502 return SboxTable[(int)a];
1535 UCHAR swap_halfs[4];
1541 for (i=0 ; i<4; i++)
1543 if ((in[i] & 0x80)== 0x80)
1549 swap_halfs[0] = in[2]; /* Swap halfs */
1550 swap_halfs[1] = in[3];
1551 swap_halfs[2] = in[0];
1552 swap_halfs[3] = in[1];
1554 rotl[0] = in[3]; /* Rotate left 8 bits */
1559 andf7[0] = in[0] & 0x7f;
1560 andf7[1] = in[1] & 0x7f;
1561 andf7[2] = in[2] & 0x7f;
1562 andf7[3] = in[3] & 0x7f;
1564 for (i = 3; i>0; i--) /* logical shift left 1 bit */
1566 andf7[i] = andf7[i] << 1;
1567 if ((andf7[i-1] & 0x80) == 0x80)
1569 andf7[i] = (andf7[i] | 0x01);
1572 andf7[0] = andf7[0] << 1;
1573 andf7[0] = andf7[0] & 0xfe;
1575 xor_32(add1b, andf7, add1bf7);
1577 xor_32(in, add1bf7, rotr);
1579 temp[0] = rotr[0]; /* Rotate right 8 bits */
1585 xor_32(add1bf7, rotr, temp);
1586 xor_32(swap_halfs, rotl,tempb);
1587 xor_32(temp, tempb, out);