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 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
38 #include "../rt_config.h"
40 UCHAR OUI_WPA_NONE_AKM
[4] = {0x00, 0x50, 0xF2, 0x00};
41 UCHAR OUI_WPA_VERSION
[4] = {0x00, 0x50, 0xF2, 0x01};
43 UCHAR OUI_WPA_WEP40
[4] = {0x00, 0x50, 0xF2, 0x01};
45 UCHAR OUI_WPA_TKIP
[4] = {0x00, 0x50, 0xF2, 0x02};
46 UCHAR OUI_WPA_CCMP
[4] = {0x00, 0x50, 0xF2, 0x04};
48 UCHAR OUI_WPA_WEP104
[4] = {0x00, 0x50, 0xF2, 0x05};
50 UCHAR OUI_WPA_8021X_AKM
[4] = {0x00, 0x50, 0xF2, 0x01};
51 UCHAR OUI_WPA_PSK_AKM
[4] = {0x00, 0x50, 0xF2, 0x02};
53 UCHAR OUI_WPA2_WEP40
[4] = {0x00, 0x0F, 0xAC, 0x01};
54 UCHAR OUI_WPA2_TKIP
[4] = {0x00, 0x0F, 0xAC, 0x02};
55 UCHAR OUI_WPA2_CCMP
[4] = {0x00, 0x0F, 0xAC, 0x04};
56 UCHAR OUI_WPA2_8021X_AKM
[4] = {0x00, 0x0F, 0xAC, 0x01};
57 UCHAR OUI_WPA2_PSK_AKM
[4] = {0x00, 0x0F, 0xAC, 0x02};
59 UCHAR OUI_WPA2_WEP104
[4] = {0x00, 0x0F, 0xAC, 0x05};
62 UCHAR OUI_MSA_8021X_AKM
[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
63 UCHAR OUI_MSA_PSK_AKM
[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
66 ========================================================================
69 The pseudo-random function(PRF) that hashes various inputs to
70 derive a pseudo-random value. To add liveness to the pseudo-random
71 value, a nonce should be one of the inputs.
73 It is used to generate PTK, GTK or some specific random value.
76 UCHAR *key, - the key material for HMAC_SHA1 use
77 INT key_len - the length of key
78 UCHAR *prefix - a prefix label
79 INT prefix_len - the length of the label
80 UCHAR *data - a specific data with variable length
81 INT data_len - the length of a specific data
82 INT len - the output lenght
85 UCHAR *output - the calculated result
88 802.11i-2004 Annex H.3
90 ========================================================================
104 INT currentindex
= 0;
107 // Allocate memory for input
108 os_alloc_mem(NULL
, (PUCHAR
*)&input
, 1024);
112 DBGPRINT(RT_DEBUG_ERROR
, ("!!!PRF: no memory!!!\n"));
116 // Generate concatenation input
117 NdisMoveMemory(input
, prefix
, prefix_len
);
119 // Concatenate a single octet containing 0
120 input
[prefix_len
] = 0;
122 // Concatenate specific data
123 NdisMoveMemory(&input
[prefix_len
+ 1], data
, data_len
);
124 total_len
= prefix_len
+ 1 + data_len
;
126 // Concatenate a single octet containing 0
127 // This octet shall be update later
128 input
[total_len
] = 0;
131 // Iterate to calculate the result by hmac-sha-1
132 // Then concatenate to last result
133 for (i
= 0; i
< (len
+ 19) / 20; i
++)
135 HMAC_SHA1(input
, total_len
, key
, key_len
, &output
[currentindex
]);
138 // update the last octet
139 input
[total_len
- 1]++;
141 os_free_mem(NULL
, input
);
145 ========================================================================
148 It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
149 It shall be called by 4-way handshake processing.
152 pAd - pointer to our pAdapter context
154 ANonce - pointer to ANonce
155 AA - pointer to Authenticator Address
156 SNonce - pointer to SNonce
157 SA - pointer to Supplicant Address
158 len - indicate the length of PTK (octet)
161 Output pointer to the PTK
164 Refer to IEEE 802.11i-2004 8.5.1.2
166 ========================================================================
169 IN PRTMP_ADAPTER pAd
,
178 UCHAR concatenation
[76];
181 UCHAR Prefix
[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
182 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
184 // initiate the concatenation input
185 NdisZeroMemory(temp
, sizeof(temp
));
186 NdisZeroMemory(concatenation
, 76);
188 // Get smaller address
189 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
190 NdisMoveMemory(concatenation
, AA
, 6);
192 NdisMoveMemory(concatenation
, SA
, 6);
195 // Get larger address
196 if (RTMPCompareMemory(SA
, AA
, 6) == 1)
197 NdisMoveMemory(&concatenation
[CurrPos
], SA
, 6);
199 NdisMoveMemory(&concatenation
[CurrPos
], AA
, 6);
201 // store the larger mac address for backward compatible of
202 // ralink proprietary STA-key issue
203 NdisMoveMemory(temp
, &concatenation
[CurrPos
], MAC_ADDR_LEN
);
207 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 0)
208 NdisMoveMemory(&concatenation
[CurrPos
], temp
, 32); // patch for ralink proprietary STA-key issue
209 else if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
210 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
212 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
216 if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 0)
217 NdisMoveMemory(&concatenation
[CurrPos
], temp
, 32); // patch for ralink proprietary STA-key issue
218 else if (RTMPCompareMemory(ANonce
, SNonce
, 32) == 1)
219 NdisMoveMemory(&concatenation
[CurrPos
], ANonce
, 32);
221 NdisMoveMemory(&concatenation
[CurrPos
], SNonce
, 32);
224 hex_dump("concatenation=", concatenation
, 76);
226 // Use PRF to generate PTK
227 PRF(PMK
, LEN_MASTER_KEY
, Prefix
, 22, concatenation
, 76, output
, len
);
232 ========================================================================
235 Generate random number by software.
238 pAd - pointer to our pAdapter context
239 macAddr - pointer to local MAC address
244 802.1ii-2004 Annex H.5
246 ========================================================================
249 IN PRTMP_ADAPTER pAd
,
254 UCHAR local
[80], KeyCounter
[32];
257 UCHAR prefix
[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
259 // Zero the related information
260 NdisZeroMemory(result
, 80);
261 NdisZeroMemory(local
, 80);
262 NdisZeroMemory(KeyCounter
, 32);
264 for (i
= 0; i
< 32; i
++)
266 // copy the local MAC address
267 COPY_MAC_ADDR(local
, macAddr
);
270 // concatenate the current time
271 NdisGetSystemUpTime(&CurrentTime
);
272 NdisMoveMemory(&local
[curr
], &CurrentTime
, sizeof(CurrentTime
));
273 curr
+= sizeof(CurrentTime
);
275 // concatenate the last result
276 NdisMoveMemory(&local
[curr
], result
, 32);
279 // concatenate a variable
280 NdisMoveMemory(&local
[curr
], &i
, 2);
283 // calculate the result
284 PRF(KeyCounter
, 32, prefix
,12, local
, curr
, result
, 32);
287 NdisMoveMemory(random
, result
, 32);
291 ========================================================================
294 Build cipher suite in RSN-IE.
295 It only shall be called by RTMPMakeRSNIE.
298 pAd - pointer to our pAdapter context
299 ElementID - indicate the WPA1 or WPA2
300 WepStatus - indicate the encryption type
301 bMixCipher - a boolean to indicate the pairwise cipher and group
302 cipher are the same or not
308 ========================================================================
310 static VOID
RTMPInsertRsnIeCipher(
311 IN PRTMP_ADAPTER pAd
,
314 IN BOOLEAN bMixCipher
,
315 IN UCHAR FlexibleCipher
,
323 // decide WPA2 or WPA1
324 if (ElementID
== Wpa2Ie
)
326 RSNIE2
*pRsnie_cipher
= (RSNIE2
*)pRsnIe
;
328 // Assign the verson as 1
329 pRsnie_cipher
->version
= 1;
334 case Ndis802_11Encryption2Enabled
:
335 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_TKIP
, 4);
336 pRsnie_cipher
->ucount
= 1;
337 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA2_TKIP
, 4);
338 *rsn_len
= sizeof(RSNIE2
);
342 case Ndis802_11Encryption3Enabled
:
344 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_TKIP
, 4);
346 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_CCMP
, 4);
347 pRsnie_cipher
->ucount
= 1;
348 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA2_CCMP
, 4);
349 *rsn_len
= sizeof(RSNIE2
);
353 case Ndis802_11Encryption4Enabled
:
354 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_TKIP
, 4);
357 // Insert WPA2 TKIP as the first pairwise cipher
358 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher
))
360 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA2_TKIP
, 4);
361 // Insert WPA2 AES as the secondary pairwise cipher
362 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher
))
364 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
+ 4, OUI_WPA2_CCMP
, 4);
370 // Insert WPA2 AES as the first pairwise cipher
371 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA2_CCMP
, 4);
374 pRsnie_cipher
->ucount
= PairwiseCnt
;
375 *rsn_len
= sizeof(RSNIE2
) + (4 * (PairwiseCnt
- 1));
380 if ((pAd
->OpMode
== OPMODE_STA
) &&
381 (pAd
->StaCfg
.GroupCipher
!= Ndis802_11Encryption2Enabled
) &&
382 (pAd
->StaCfg
.GroupCipher
!= Ndis802_11Encryption3Enabled
))
384 UINT GroupCipher
= pAd
->StaCfg
.GroupCipher
;
387 case Ndis802_11GroupWEP40Enabled
:
388 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_WEP40
, 4);
390 case Ndis802_11GroupWEP104Enabled
:
391 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA2_WEP104
, 4);
396 // swap for big-endian platform
397 pRsnie_cipher
->version
= cpu2le16(pRsnie_cipher
->version
);
398 pRsnie_cipher
->ucount
= cpu2le16(pRsnie_cipher
->ucount
);
402 RSNIE
*pRsnie_cipher
= (RSNIE
*)pRsnIe
;
404 // Assign OUI and version
405 NdisMoveMemory(pRsnie_cipher
->oui
, OUI_WPA_VERSION
, 4);
406 pRsnie_cipher
->version
= 1;
411 case Ndis802_11Encryption2Enabled
:
412 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_TKIP
, 4);
413 pRsnie_cipher
->ucount
= 1;
414 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA_TKIP
, 4);
415 *rsn_len
= sizeof(RSNIE
);
419 case Ndis802_11Encryption3Enabled
:
421 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_TKIP
, 4);
423 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_CCMP
, 4);
424 pRsnie_cipher
->ucount
= 1;
425 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA_CCMP
, 4);
426 *rsn_len
= sizeof(RSNIE
);
430 case Ndis802_11Encryption4Enabled
:
431 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_TKIP
, 4);
434 // Insert WPA TKIP as the first pairwise cipher
435 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher
))
437 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA_TKIP
, 4);
438 // Insert WPA AES as the secondary pairwise cipher
439 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher
))
441 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
+ 4, OUI_WPA_CCMP
, 4);
447 // Insert WPA AES as the first pairwise cipher
448 NdisMoveMemory(pRsnie_cipher
->ucast
[0].oui
, OUI_WPA_CCMP
, 4);
451 pRsnie_cipher
->ucount
= PairwiseCnt
;
452 *rsn_len
= sizeof(RSNIE
) + (4 * (PairwiseCnt
- 1));
457 if ((pAd
->OpMode
== OPMODE_STA
) &&
458 (pAd
->StaCfg
.GroupCipher
!= Ndis802_11Encryption2Enabled
) &&
459 (pAd
->StaCfg
.GroupCipher
!= Ndis802_11Encryption3Enabled
))
461 UINT GroupCipher
= pAd
->StaCfg
.GroupCipher
;
464 case Ndis802_11GroupWEP40Enabled
:
465 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_WEP40
, 4);
467 case Ndis802_11GroupWEP104Enabled
:
468 NdisMoveMemory(pRsnie_cipher
->mcast
, OUI_WPA_WEP104
, 4);
473 // swap for big-endian platform
474 pRsnie_cipher
->version
= cpu2le16(pRsnie_cipher
->version
);
475 pRsnie_cipher
->ucount
= cpu2le16(pRsnie_cipher
->ucount
);
480 ========================================================================
483 Build AKM suite in RSN-IE.
484 It only shall be called by RTMPMakeRSNIE.
487 pAd - pointer to our pAdapter context
488 ElementID - indicate the WPA1 or WPA2
489 AuthMode - indicate the authentication mode
490 apidx - indicate the interface index
496 ========================================================================
498 static VOID
RTMPInsertRsnIeAKM(
499 IN PRTMP_ADAPTER pAd
,
506 RSNIE_AUTH
*pRsnie_auth
;
508 pRsnie_auth
= (RSNIE_AUTH
*)(pRsnIe
+ (*rsn_len
));
510 // decide WPA2 or WPA1
511 if (ElementID
== Wpa2Ie
)
515 case Ndis802_11AuthModeWPA2
:
516 case Ndis802_11AuthModeWPA1WPA2
:
517 pRsnie_auth
->acount
= 1;
518 NdisMoveMemory(pRsnie_auth
->auth
[0].oui
, OUI_WPA2_8021X_AKM
, 4);
521 case Ndis802_11AuthModeWPA2PSK
:
522 case Ndis802_11AuthModeWPA1PSKWPA2PSK
:
523 pRsnie_auth
->acount
= 1;
524 NdisMoveMemory(pRsnie_auth
->auth
[0].oui
, OUI_WPA2_PSK_AKM
, 4);
532 case Ndis802_11AuthModeWPA
:
533 case Ndis802_11AuthModeWPA1WPA2
:
534 pRsnie_auth
->acount
= 1;
535 NdisMoveMemory(pRsnie_auth
->auth
[0].oui
, OUI_WPA_8021X_AKM
, 4);
538 case Ndis802_11AuthModeWPAPSK
:
539 case Ndis802_11AuthModeWPA1PSKWPA2PSK
:
540 pRsnie_auth
->acount
= 1;
541 NdisMoveMemory(pRsnie_auth
->auth
[0].oui
, OUI_WPA_PSK_AKM
, 4);
544 case Ndis802_11AuthModeWPANone
:
545 pRsnie_auth
->acount
= 1;
546 NdisMoveMemory(pRsnie_auth
->auth
[0].oui
, OUI_WPA_NONE_AKM
, 4);
551 pRsnie_auth
->acount
= cpu2le16(pRsnie_auth
->acount
);
553 (*rsn_len
) += sizeof(RSNIE_AUTH
); // update current RSNIE length
558 ========================================================================
561 Build capability in RSN-IE.
562 It only shall be called by RTMPMakeRSNIE.
565 pAd - pointer to our pAdapter context
566 ElementID - indicate the WPA1 or WPA2
567 apidx - indicate the interface index
573 ========================================================================
575 static VOID
RTMPInsertRsnIeCap(
576 IN PRTMP_ADAPTER pAd
,
582 RSN_CAPABILITIES
*pRSN_Cap
;
584 // it could be ignored in WPA1 mode
585 if (ElementID
== WpaIe
)
588 pRSN_Cap
= (RSN_CAPABILITIES
*)(pRsnIe
+ (*rsn_len
));
591 pRSN_Cap
->word
= cpu2le16(pRSN_Cap
->word
);
593 (*rsn_len
) += sizeof(RSN_CAPABILITIES
); // update current RSNIE length
599 ========================================================================
602 Build RSN IE context. It is not included element-ID and length.
605 pAd - pointer to our pAdapter context
606 AuthMode - indicate the authentication mode
607 WepStatus - indicate the encryption type
608 apidx - indicate the interface index
614 ========================================================================
617 IN PRTMP_ADAPTER pAd
,
622 PUCHAR pRsnIe
= NULL
; // primary RSNIE
623 UCHAR
*rsnielen_cur_p
= 0; // the length of the primary RSNIE
624 UCHAR
*rsnielen_ex_cur_p
= 0; // the length of the secondary RSNIE
626 BOOLEAN bMixCipher
= FALSE
; // indicate the pairwise and group cipher are different
628 WPA_MIX_PAIR_CIPHER FlexibleCipher
= WPA_TKIPAES_WPA2_TKIPAES
; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
630 rsnielen_cur_p
= NULL
;
631 rsnielen_ex_cur_p
= NULL
;
635 if (pAd
->StaCfg
.WpaSupplicantUP
!= WPA_SUPPLICANT_DISABLE
)
637 if (AuthMode
< Ndis802_11AuthModeWPA
)
642 // Support WPAPSK or WPA2PSK in STA-Infra mode
643 // Support WPANone in STA-Adhoc mode
644 if ((AuthMode
!= Ndis802_11AuthModeWPAPSK
) &&
645 (AuthMode
!= Ndis802_11AuthModeWPA2PSK
) &&
646 (AuthMode
!= Ndis802_11AuthModeWPANone
)
651 DBGPRINT(RT_DEBUG_TRACE
,("==> RTMPMakeRSNIE(STA)\n"));
653 // Zero RSNIE context
654 pAd
->StaCfg
.RSNIE_Len
= 0;
655 NdisZeroMemory(pAd
->StaCfg
.RSN_IE
, MAX_LEN_OF_RSNIE
);
658 rsnielen_cur_p
= &pAd
->StaCfg
.RSNIE_Len
;
659 pRsnIe
= pAd
->StaCfg
.RSN_IE
;
661 bMixCipher
= pAd
->StaCfg
.bMixCipher
;
665 // indicate primary RSNIE as WPA or WPA2
666 if ((AuthMode
== Ndis802_11AuthModeWPA
) ||
667 (AuthMode
== Ndis802_11AuthModeWPAPSK
) ||
668 (AuthMode
== Ndis802_11AuthModeWPANone
) ||
669 (AuthMode
== Ndis802_11AuthModeWPA1WPA2
) ||
670 (AuthMode
== Ndis802_11AuthModeWPA1PSKWPA2PSK
))
671 PrimaryRsnie
= WpaIe
;
673 PrimaryRsnie
= Wpa2Ie
;
676 // Build the primary RSNIE
677 // 1. insert cipher suite
678 RTMPInsertRsnIeCipher(pAd
, PrimaryRsnie
, WepStatus
, bMixCipher
, FlexibleCipher
, pRsnIe
, &p_offset
);
681 RTMPInsertRsnIeAKM(pAd
, PrimaryRsnie
, AuthMode
, apidx
, pRsnIe
, &p_offset
);
683 // 3. insert capability
684 RTMPInsertRsnIeCap(pAd
, PrimaryRsnie
, apidx
, pRsnIe
, &p_offset
);
687 // 4. update the RSNIE length
688 *rsnielen_cur_p
= p_offset
;
690 hex_dump("The primary RSNIE", pRsnIe
, (*rsnielen_cur_p
));
696 ==========================================================================
698 Check whether the received frame is EAP frame.
701 pAd - pointer to our pAdapter context
702 pEntry - pointer to active entry
703 pData - the received frame
704 DataByteCount - the received frame's length
705 FromWhichBSSID - indicate the interface index
708 TRUE - This frame is EAP frame
710 ==========================================================================
712 BOOLEAN
RTMPCheckWPAframe(
713 IN PRTMP_ADAPTER pAd
,
714 IN PMAC_TABLE_ENTRY pEntry
,
716 IN ULONG DataByteCount
,
717 IN UCHAR FromWhichBSSID
)
723 if(DataByteCount
< (LENGTH_802_1_H
+ LENGTH_EAPOL_H
))
728 if (NdisEqualMemory(SNAP_802_1H
, pData
, 6) ||
729 // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
730 NdisEqualMemory(SNAP_BRIDGE_TUNNEL
, pData
, 6))
734 // Skip 2-bytes EAPoL type
735 if (NdisEqualMemory(EAPOL
, pData
, 2))
745 Body_len
= (*(pData
+2)<<8) | (*(pData
+3));
746 DBGPRINT(RT_DEBUG_TRACE
, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len
));
749 DBGPRINT(RT_DEBUG_TRACE
, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
750 if (pEntry
->EnqueueEapolStartTimerRunning
!= EAPOL_START_DISABLE
)
752 DBGPRINT(RT_DEBUG_TRACE
, ("Cancel the EnqueueEapolStartTimerRunning \n"));
753 RTMPCancelTimer(&pEntry
->EnqueueStartForPSKTimer
, &Cancelled
);
754 pEntry
->EnqueueEapolStartTimerRunning
= EAPOL_START_DISABLE
;
758 DBGPRINT(RT_DEBUG_TRACE
, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
761 Body_len
= (*(pData
+2)<<8) | (*(pData
+3));
762 DBGPRINT(RT_DEBUG_TRACE
, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len
));
765 DBGPRINT(RT_DEBUG_TRACE
, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
776 ==========================================================================
778 ENCRYPT AES GTK before sending in EAPOL frame.
779 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
780 This function references to RFC 3394 for aes key wrap algorithm.
782 ==========================================================================
784 VOID
AES_GTK_KEY_WRAP(
788 OUT UCHAR
*ciphertext
)
790 UCHAR A
[8], BIN
[16], BOUT
[16];
792 INT num_blocks
= p_len
/8; // unit:64bits
797 rtmp_aes_set_key(&aesctx
, key
, 128);
800 for (i
= 0; i
< 8; i
++)
804 for (i
= 0; i
< num_blocks
; i
++)
806 for (j
= 0 ; j
< 8; j
++)
807 R
[8 * (i
+ 1) + j
] = plaintext
[8 * i
+ j
];
811 for (j
= 0; j
< 6; j
++)
813 for(i
= 1; i
<= num_blocks
; i
++)
816 NdisMoveMemory(BIN
, A
, 8);
817 NdisMoveMemory(&BIN
[8], &R
[8 * i
], 8);
818 rtmp_aes_encrypt(&aesctx
, BIN
, BOUT
);
820 NdisMoveMemory(A
, &BOUT
[0], 8);
821 xor = num_blocks
* j
+ i
;
822 A
[7] = BOUT
[7] ^ xor;
823 NdisMoveMemory(&R
[8 * i
], &BOUT
[8], 8);
828 NdisMoveMemory(ciphertext
, A
, 8);
830 for (i
= 1; i
<= num_blocks
; i
++)
832 for (j
= 0 ; j
< 8; j
++)
833 ciphertext
[8 * i
+ j
] = R
[8 * i
+ j
];
839 ========================================================================
842 Misc function to decrypt AES body
849 This function references to RFC 3394 for aes key unwrap algorithm.
851 ========================================================================
853 VOID
AES_GTK_KEY_UNWRAP(
855 OUT UCHAR
*plaintext
,
857 IN UCHAR
*ciphertext
)
860 UCHAR A
[8], BIN
[16], BOUT
[16];
865 INT num_blocks
= c_len
/8; // unit:64bits
868 os_alloc_mem(NULL
, (PUCHAR
*)&R
, 512);
872 DBGPRINT(RT_DEBUG_ERROR
, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
877 NdisMoveMemory(A
, ciphertext
, 8);
879 for(i
= 0; i
< (c_len
-8); i
++)
881 R
[ i
] = ciphertext
[i
+ 8];
884 rtmp_aes_set_key(&aesctx
, key
, 128);
886 for(j
= 5; j
>= 0; j
--)
888 for(i
= (num_blocks
-1); i
> 0; i
--)
890 xor = (num_blocks
-1 )* j
+ i
;
891 NdisMoveMemory(BIN
, A
, 8);
893 NdisMoveMemory(&BIN
[8], &R
[(i
-1)*8], 8);
894 rtmp_aes_decrypt(&aesctx
, BIN
, BOUT
);
895 NdisMoveMemory(A
, &BOUT
[0], 8);
896 NdisMoveMemory(&R
[(i
-1)*8], &BOUT
[8], 8);
901 for(i
= 0; i
< c_len
; i
++)
907 os_free_mem(NULL
, R
);
911 ==========================================================================
913 Report the EAP message type
916 msg - EAPOL_PAIR_MSG_1
926 ==========================================================================
928 CHAR
*GetEapolMsgType(CHAR msg
)
930 if(msg
== EAPOL_PAIR_MSG_1
)
931 return "Pairwise Message 1";
932 else if(msg
== EAPOL_PAIR_MSG_2
)
933 return "Pairwise Message 2";
934 else if(msg
== EAPOL_PAIR_MSG_3
)
935 return "Pairwise Message 3";
936 else if(msg
== EAPOL_PAIR_MSG_4
)
937 return "Pairwise Message 4";
938 else if(msg
== EAPOL_GROUP_MSG_1
)
939 return "Group Message 1";
940 else if(msg
== EAPOL_GROUP_MSG_2
)
941 return "Group Message 2";
943 return "Invalid Message";
948 ========================================================================
951 Check Sanity RSN IE of EAPoL message
958 ========================================================================
960 BOOLEAN
RTMPCheckRSNIE(
961 IN PRTMP_ADAPTER pAd
,
964 IN MAC_TABLE_ENTRY
*pEntry
,
970 BOOLEAN result
= FALSE
;
976 while (len
> sizeof(RSNIE2
))
978 pEid
= (PEID_STRUCT
) pVIE
;
980 if ((pEid
->Eid
== IE_WPA
) && (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4)))
982 if ((pEntry
->AuthMode
== Ndis802_11AuthModeWPA
|| pEntry
->AuthMode
== Ndis802_11AuthModeWPAPSK
) &&
983 (NdisEqualMemory(pVIE
, pEntry
->RSN_IE
, pEntry
->RSNIE_Len
)) &&
984 (pEntry
->RSNIE_Len
== (pEid
->Len
+ 2)))
989 *Offset
+= (pEid
->Len
+ 2);
992 else if ((pEid
->Eid
== IE_RSN
) && (NdisEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3)))
994 if ((pEntry
->AuthMode
== Ndis802_11AuthModeWPA2
|| pEntry
->AuthMode
== Ndis802_11AuthModeWPA2PSK
) &&
995 (NdisEqualMemory(pVIE
, pEntry
->RSN_IE
, pEntry
->RSNIE_Len
)) &&
996 (pEntry
->RSNIE_Len
== (pEid
->Len
+ 2))/* ToDo-AlbertY for mesh*/)
1001 *Offset
+= (pEid
->Len
+ 2);
1008 pVIE
+= (pEid
->Len
+ 2);
1009 len
-= (pEid
->Len
+ 2);
1019 ========================================================================
1021 Routine Description:
1022 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1023 GTK is encaptulated in KDE format at p.83 802.11i D10
1032 ========================================================================
1034 BOOLEAN
RTMPParseEapolKeyData(
1035 IN PRTMP_ADAPTER pAd
,
1037 IN UCHAR KeyDataLen
,
1038 IN UCHAR GroupKeyIndex
,
1041 IN MAC_TABLE_ENTRY
*pEntry
)
1043 PKDE_ENCAP pKDE
= NULL
;
1044 PUCHAR pMyKeyData
= pKeyData
;
1045 UCHAR KeyDataLength
= KeyDataLen
;
1047 UCHAR DefaultIdx
= 0;
1050 // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
1051 if (MsgType
== EAPOL_PAIR_MSG_2
|| MsgType
== EAPOL_PAIR_MSG_3
)
1053 // Check RSN IE whether it is WPA2/WPA2PSK
1054 if (!RTMPCheckRSNIE(pAd
, pKeyData
, KeyDataLen
, pEntry
, &skip_offset
))
1056 // send wireless event - for RSN IE different
1057 if (pAd
->CommonCfg
.bWirelessEvent
)
1058 RTMPSendWirelessEvent(pAd
, IW_RSNIE_DIFF_EVENT_FLAG
, pEntry
->Addr
, pEntry
->apidx
, 0);
1060 DBGPRINT(RT_DEBUG_ERROR
, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType
));
1061 hex_dump("Receive RSN_IE ", pKeyData
, KeyDataLen
);
1062 hex_dump("Desired RSN_IE ", pEntry
->RSN_IE
, pEntry
->RSNIE_Len
);
1068 if (bWPA2
&& MsgType
== EAPOL_PAIR_MSG_3
)
1071 pMyKeyData
+= skip_offset
;
1072 KeyDataLength
-= skip_offset
;
1073 DBGPRINT(RT_DEBUG_TRACE
, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset
));
1080 DBGPRINT(RT_DEBUG_TRACE
,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength
));
1082 // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
1083 if (bWPA2
&& (MsgType
== EAPOL_PAIR_MSG_3
|| MsgType
== EAPOL_GROUP_MSG_1
))
1085 if (KeyDataLength
>= 8) // KDE format exclude GTK length
1087 pKDE
= (PKDE_ENCAP
) pMyKeyData
;
1090 DefaultIdx
= pKDE
->GTKEncap
.Kid
;
1092 // Sanity check - KED length
1093 if (KeyDataLength
< (pKDE
->Len
+ 2))
1095 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR: The len from KDE is too short \n"));
1099 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1100 GTKLEN
= pKDE
->Len
-6;
1101 if (GTKLEN
< LEN_AES_KEY
)
1103 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN
));
1110 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR: KDE format length is too short \n"));
1114 DBGPRINT(RT_DEBUG_TRACE
, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx
, GTKLEN
));
1120 else if (!bWPA2
&& MsgType
== EAPOL_GROUP_MSG_1
)
1122 DefaultIdx
= GroupKeyIndex
;
1123 DBGPRINT(RT_DEBUG_TRACE
, ("GTK DefaultKeyID=%d \n", DefaultIdx
));
1126 // Sanity check - shared key index must be 1 ~ 3
1127 if (DefaultIdx
< 1 || DefaultIdx
> 3)
1129 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx
, ((bWPA2
) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType
)));
1139 ========================================================================
1141 Routine Description:
1142 Construct EAPoL message for WPA handshaking
1143 Its format is below,
1145 +--------------------+
1146 | Protocol Version | 1 octet
1147 +--------------------+
1148 | Protocol Type | 1 octet
1149 +--------------------+
1150 | Body Length | 2 octets
1151 +--------------------+
1152 | Descriptor Type | 1 octet
1153 +--------------------+
1154 | Key Information | 2 octets
1155 +--------------------+
1156 | Key Length | 1 octet
1157 +--------------------+
1158 | Key Repaly Counter | 8 octets
1159 +--------------------+
1160 | Key Nonce | 32 octets
1161 +--------------------+
1162 | Key IV | 16 octets
1163 +--------------------+
1164 | Key RSC | 8 octets
1165 +--------------------+
1166 | Key ID or Reserved | 8 octets
1167 +--------------------+
1168 | Key MIC | 16 octets
1169 +--------------------+
1170 | Key Data Length | 2 octets
1171 +--------------------+
1172 | Key Data | n octets
1173 +--------------------+
1177 pAd Pointer to our adapter
1184 ========================================================================
1186 VOID
ConstructEapolMsg(
1187 IN PRTMP_ADAPTER pAd
,
1190 IN UCHAR GroupKeyWepStatus
,
1192 IN UCHAR DefaultKeyIdx
,
1193 IN UCHAR
*ReplayCounter
,
1200 OUT PEAPOL_PACKET pMsg
)
1202 BOOLEAN bWPA2
= FALSE
;
1204 // Choose WPA2 or not
1205 if ((AuthMode
== Ndis802_11AuthModeWPA2
) || (AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1208 // Init Packet and Fill header
1209 pMsg
->ProVer
= EAPOL_VER
;
1210 pMsg
->ProType
= EAPOLKey
;
1212 // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
1213 pMsg
->Body_Len
[1] = LEN_EAPOL_KEY_MSG
;
1215 // Fill in EAPoL descriptor
1217 pMsg
->KeyDesc
.Type
= WPA2_KEY_DESC
;
1219 pMsg
->KeyDesc
.Type
= WPA1_KEY_DESC
;
1221 // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
1222 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
1223 pMsg
->KeyDesc
.KeyInfo
.KeyDescVer
=
1224 (((WepStatus
== Ndis802_11Encryption3Enabled
) || (GroupKeyWepStatus
== Ndis802_11Encryption3Enabled
)) ? (DESC_TYPE_AES
) : (DESC_TYPE_TKIP
));
1226 // Specify Key Type as Group(0) or Pairwise(1)
1227 if (MsgType
>= EAPOL_GROUP_MSG_1
)
1228 pMsg
->KeyDesc
.KeyInfo
.KeyType
= GROUPKEY
;
1230 pMsg
->KeyDesc
.KeyInfo
.KeyType
= PAIRWISEKEY
;
1232 // Specify Key Index, only group_msg1_WPA1
1233 if (!bWPA2
&& (MsgType
>= EAPOL_GROUP_MSG_1
))
1234 pMsg
->KeyDesc
.KeyInfo
.KeyIndex
= DefaultKeyIdx
;
1236 if (MsgType
== EAPOL_PAIR_MSG_3
)
1237 pMsg
->KeyDesc
.KeyInfo
.Install
= 1;
1239 if ((MsgType
== EAPOL_PAIR_MSG_1
) || (MsgType
== EAPOL_PAIR_MSG_3
) || (MsgType
== EAPOL_GROUP_MSG_1
))
1240 pMsg
->KeyDesc
.KeyInfo
.KeyAck
= 1;
1242 if (MsgType
!= EAPOL_PAIR_MSG_1
)
1243 pMsg
->KeyDesc
.KeyInfo
.KeyMic
= 1;
1245 if ((bWPA2
&& (MsgType
>= EAPOL_PAIR_MSG_3
)) || (!bWPA2
&& (MsgType
>= EAPOL_GROUP_MSG_1
)))
1247 pMsg
->KeyDesc
.KeyInfo
.Secure
= 1;
1250 if (bWPA2
&& ((MsgType
== EAPOL_PAIR_MSG_3
) || (MsgType
== EAPOL_GROUP_MSG_1
)))
1252 pMsg
->KeyDesc
.KeyInfo
.EKD_DL
= 1;
1255 // key Information element has done.
1256 *(USHORT
*)(&pMsg
->KeyDesc
.KeyInfo
) = cpu2le16(*(USHORT
*)(&pMsg
->KeyDesc
.KeyInfo
));
1258 // Fill in Key Length
1260 if (MsgType
>= EAPOL_GROUP_MSG_1
)
1262 // the length of group key cipher
1263 pMsg
->KeyDesc
.KeyLength
[1] = ((GroupKeyWepStatus
== Ndis802_11Encryption2Enabled
) ? TKIP_GTK_LENGTH
: LEN_AES_KEY
);
1267 // the length of pairwise key cipher
1268 pMsg
->KeyDesc
.KeyLength
[1] = ((WepStatus
== Ndis802_11Encryption2Enabled
) ? LEN_TKIP_KEY
: LEN_AES_KEY
);
1272 // Fill in replay counter
1273 NdisMoveMemory(pMsg
->KeyDesc
.ReplayCounter
, ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1275 // Fill Key Nonce field
1276 // ANonce : pairwise_msg1 & pairwise_msg3
1277 // SNonce : pairwise_msg2
1278 // GNonce : group_msg1_wpa1
1279 if ((MsgType
<= EAPOL_PAIR_MSG_3
) || ((!bWPA2
&& (MsgType
== EAPOL_GROUP_MSG_1
))))
1280 NdisMoveMemory(pMsg
->KeyDesc
.KeyNonce
, KeyNonce
, LEN_KEY_DESC_NONCE
);
1282 // Fill key IV - WPA2 as 0, WPA1 as random
1283 if (!bWPA2
&& (MsgType
== EAPOL_GROUP_MSG_1
))
1285 // Suggest IV be random number plus some number,
1286 NdisMoveMemory(pMsg
->KeyDesc
.KeyIv
, &KeyNonce
[16], LEN_KEY_DESC_IV
);
1287 pMsg
->KeyDesc
.KeyIv
[15] += 2;
1290 // Fill Key RSC field
1291 // It contains the RSC for the GTK being installed.
1292 if ((MsgType
== EAPOL_PAIR_MSG_3
&& bWPA2
) || (MsgType
== EAPOL_GROUP_MSG_1
))
1294 NdisMoveMemory(pMsg
->KeyDesc
.KeyRsc
, TxRSC
, 6);
1297 // Clear Key MIC field for MIC calculation later
1298 NdisZeroMemory(pMsg
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1300 ConstructEapolKeyData(pAd
,
1313 // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
1314 if (MsgType
!= EAPOL_PAIR_MSG_1
)
1316 CalculateMIC(pAd
, WepStatus
, PTK
, pMsg
);
1319 DBGPRINT(RT_DEBUG_TRACE
, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2
) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType
)));
1320 DBGPRINT(RT_DEBUG_TRACE
, (" Body length = %d \n", pMsg
->Body_Len
[1]));
1321 DBGPRINT(RT_DEBUG_TRACE
, (" Key length = %d \n", pMsg
->KeyDesc
.KeyLength
[1]));
1327 ========================================================================
1329 Routine Description:
1330 Construct the Key Data field of EAPoL message
1333 pAd Pointer to our adapter
1341 ========================================================================
1343 VOID
ConstructEapolKeyData(
1344 IN PRTMP_ADAPTER pAd
,
1347 IN UCHAR GroupKeyWepStatus
,
1349 IN UCHAR DefaultKeyIdx
,
1350 IN BOOLEAN bWPA2Capable
,
1355 OUT PEAPOL_PACKET pMsg
)
1357 UCHAR
*mpool
, *Key_Data
, *Rc4GTK
;
1358 UCHAR ekey
[(LEN_KEY_DESC_IV
+LEN_EAP_EK
)];
1362 if (MsgType
== EAPOL_PAIR_MSG_1
|| MsgType
== EAPOL_PAIR_MSG_4
|| MsgType
== EAPOL_GROUP_MSG_2
)
1365 // allocate memory pool
1366 os_alloc_mem(pAd
, (PUCHAR
*)&mpool
, 1500);
1371 /* Rc4GTK Len = 512 */
1372 Rc4GTK
= (UCHAR
*) ROUND_UP(mpool
, 4);
1373 /* Key_Data Len = 512 */
1374 Key_Data
= (UCHAR
*) ROUND_UP(Rc4GTK
+ 512, 4);
1376 NdisZeroMemory(Key_Data
, 512);
1377 pMsg
->KeyDesc
.KeyDataLen
[1] = 0;
1380 // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
1381 if (RSNIE_LEN
&& ((MsgType
== EAPOL_PAIR_MSG_2
) || (MsgType
== EAPOL_PAIR_MSG_3
)))
1384 Key_Data
[data_offset
+ 0] = IE_WPA2
;
1386 Key_Data
[data_offset
+ 0] = IE_WPA
;
1388 Key_Data
[data_offset
+ 1] = RSNIE_LEN
;
1389 NdisMoveMemory(&Key_Data
[data_offset
+ 2], RSNIE
, RSNIE_LEN
);
1390 data_offset
+= (2 + RSNIE_LEN
);
1393 // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
1394 if (bWPA2Capable
&& ((MsgType
== EAPOL_PAIR_MSG_3
) || (MsgType
== EAPOL_GROUP_MSG_1
)))
1396 // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
1397 Key_Data
[data_offset
+ 0] = 0xDD;
1399 if (GroupKeyWepStatus
== Ndis802_11Encryption3Enabled
)
1401 Key_Data
[data_offset
+ 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
1405 Key_Data
[data_offset
+ 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
1408 Key_Data
[data_offset
+ 2] = 0x00;
1409 Key_Data
[data_offset
+ 3] = 0x0F;
1410 Key_Data
[data_offset
+ 4] = 0xAC;
1411 Key_Data
[data_offset
+ 5] = 0x01;
1413 // GTK KDE format - 802.11i-2004 Figure-43x
1414 Key_Data
[data_offset
+ 6] = (DefaultKeyIdx
& 0x03);
1415 Key_Data
[data_offset
+ 7] = 0x00; // Reserved Byte
1421 // Encapsulate GTK and encrypt the key-data field with KEK.
1422 // Only for pairwise_msg3_WPA2 and group_msg1
1423 if ((MsgType
== EAPOL_PAIR_MSG_3
&& bWPA2Capable
) || (MsgType
== EAPOL_GROUP_MSG_1
))
1426 if (GroupKeyWepStatus
== Ndis802_11Encryption3Enabled
)
1428 NdisMoveMemory(&Key_Data
[data_offset
], GTK
, LEN_AES_KEY
);
1429 data_offset
+= LEN_AES_KEY
;
1433 NdisMoveMemory(&Key_Data
[data_offset
], GTK
, TKIP_GTK_LENGTH
);
1434 data_offset
+= TKIP_GTK_LENGTH
;
1437 // Still dont know why, but if not append will occur "GTK not include in MSG3"
1438 // Patch for compatibility between zero config and funk
1439 if (MsgType
== EAPOL_PAIR_MSG_3
&& bWPA2Capable
)
1441 if (GroupKeyWepStatus
== Ndis802_11Encryption3Enabled
)
1443 Key_Data
[data_offset
+ 0] = 0xDD;
1444 Key_Data
[data_offset
+ 1] = 0;
1449 Key_Data
[data_offset
+ 0] = 0xDD;
1450 Key_Data
[data_offset
+ 1] = 0;
1451 Key_Data
[data_offset
+ 2] = 0;
1452 Key_Data
[data_offset
+ 3] = 0;
1453 Key_Data
[data_offset
+ 4] = 0;
1454 Key_Data
[data_offset
+ 5] = 0;
1459 // Encrypt the data material in key data field
1460 if (WepStatus
== Ndis802_11Encryption3Enabled
)
1462 AES_GTK_KEY_WRAP(&PTK
[16], Key_Data
, data_offset
, Rc4GTK
);
1463 // AES wrap function will grow 8 bytes in length
1468 // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
1469 // put TxTsc in Key RSC field
1470 pAd
->PrivateInfo
.FCSCRC32
= PPPINITFCS32
; //Init crc32.
1472 // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
1473 NdisMoveMemory(ekey
, pMsg
->KeyDesc
.KeyIv
, LEN_KEY_DESC_IV
);
1474 NdisMoveMemory(&ekey
[LEN_KEY_DESC_IV
], &PTK
[16], LEN_EAP_EK
);
1475 ARCFOUR_INIT(&pAd
->PrivateInfo
.WEPCONTEXT
, ekey
, sizeof(ekey
)); //INIT SBOX, KEYLEN+3(IV)
1476 pAd
->PrivateInfo
.FCSCRC32
= RTMP_CALC_FCS32(pAd
->PrivateInfo
.FCSCRC32
, Key_Data
, data_offset
);
1477 WPAARCFOUR_ENCRYPT(&pAd
->PrivateInfo
.WEPCONTEXT
, Rc4GTK
, Key_Data
, data_offset
);
1480 NdisMoveMemory(pMsg
->KeyDesc
.KeyData
, Rc4GTK
, data_offset
);
1484 NdisMoveMemory(pMsg
->KeyDesc
.KeyData
, Key_Data
, data_offset
);
1487 // set key data length field and total length
1488 pMsg
->KeyDesc
.KeyDataLen
[1] = data_offset
;
1489 pMsg
->Body_Len
[1] += data_offset
;
1491 os_free_mem(pAd
, mpool
);
1496 ========================================================================
1498 Routine Description:
1499 Calcaulate MIC. It is used during 4-ways handsharking.
1502 pAd - pointer to our pAdapter context
1503 PeerWepStatus - indicate the encryption type
1509 ========================================================================
1512 IN PRTMP_ADAPTER pAd
,
1513 IN UCHAR PeerWepStatus
,
1515 OUT PEAPOL_PACKET pMsg
)
1519 UCHAR mic
[LEN_KEY_DESC_MIC
];
1522 // allocate memory for MIC calculation
1523 os_alloc_mem(pAd
, (PUCHAR
*)&OutBuffer
, 512);
1525 if (OutBuffer
== NULL
)
1527 DBGPRINT(RT_DEBUG_ERROR
, ("!!!CalculateMIC: no memory!!!\n"));
1531 // make a frame for calculating MIC.
1532 MakeOutgoingFrame(OutBuffer
, &FrameLen
,
1533 pMsg
->Body_Len
[1] + 4, pMsg
,
1536 NdisZeroMemory(mic
, sizeof(mic
));
1539 if (PeerWepStatus
== Ndis802_11Encryption3Enabled
)
1541 HMAC_SHA1(OutBuffer
, FrameLen
, PTK
, LEN_EAP_MICK
, digest
);
1542 NdisMoveMemory(mic
, digest
, LEN_KEY_DESC_MIC
);
1546 hmac_md5(PTK
, LEN_EAP_MICK
, OutBuffer
, FrameLen
, mic
);
1549 // store the calculated MIC
1550 NdisMoveMemory(pMsg
->KeyDesc
.KeyMic
, mic
, LEN_KEY_DESC_MIC
);
1552 os_free_mem(pAd
, OutBuffer
);
1556 ========================================================================
1558 Routine Description:
1559 Some received frames can't decrypt by Asic, so decrypt them by software.
1562 pAd - pointer to our pAdapter context
1563 PeerWepStatus - indicate the encryption type
1566 NDIS_STATUS_SUCCESS - decryption successful
1567 NDIS_STATUS_FAILURE - decryption failure
1569 ========================================================================
1571 NDIS_STATUS
RTMPSoftDecryptBroadCastData(
1572 IN PRTMP_ADAPTER pAd
,
1574 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher
,
1575 IN PCIPHER_KEY pShard_key
)
1577 PRXWI_STRUC pRxWI
= pRxBlk
->pRxWI
;
1581 // handle WEP decryption
1582 if (GroupCipher
== Ndis802_11Encryption1Enabled
)
1584 if (RTMPSoftDecryptWEP(pAd
, pRxBlk
->pData
, pRxWI
->MPDUtotalByteCount
, pShard_key
))
1587 //Minus IV[4] & ICV[4]
1588 pRxWI
->MPDUtotalByteCount
-= 8;
1592 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR : Software decrypt WEP data fails.\n"));
1593 // give up this frame
1594 return NDIS_STATUS_FAILURE
;
1597 // handle TKIP decryption
1598 else if (GroupCipher
== Ndis802_11Encryption2Enabled
)
1600 if (RTMPSoftDecryptTKIP(pAd
, pRxBlk
->pData
, pRxWI
->MPDUtotalByteCount
, 0, pShard_key
))
1603 //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
1604 pRxWI
->MPDUtotalByteCount
-= 20;
1608 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
1609 // give up this frame
1610 return NDIS_STATUS_FAILURE
;
1613 // handle AES decryption
1614 else if (GroupCipher
== Ndis802_11Encryption3Enabled
)
1616 if (RTMPSoftDecryptAES(pAd
, pRxBlk
->pData
, pRxWI
->MPDUtotalByteCount
, pShard_key
))
1619 //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
1620 pRxWI
->MPDUtotalByteCount
-= 16;
1624 DBGPRINT(RT_DEBUG_ERROR
, ("ERROR : RTMPSoftDecryptAES Failed\n"));
1625 // give up this frame
1626 return NDIS_STATUS_FAILURE
;
1631 // give up this frame
1632 return NDIS_STATUS_FAILURE
;
1635 return NDIS_STATUS_SUCCESS
;