diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2011-04-08 20:33:25 -0500 |
---|---|---|
committer | Larry Finger <Larry.Finger@lwfinger.net> | 2011-04-08 20:33:25 -0500 |
commit | fefecc6989b4b24276797270c0e229c07be02ad3 (patch) | |
tree | 7c03f0f798ab84e5cf0c14a6648c991efd37c160 /drivers/staging/rt2860/common/cmm_wpa.c | |
parent | 0c3efe54d0165cecf0698b468e253577b555dde6 (diff) | |
download | linux-stable-fefecc6989b4b24276797270c0e229c07be02ad3.tar.gz linux-stable-fefecc6989b4b24276797270c0e229c07be02ad3.tar.bz2 linux-stable-fefecc6989b4b24276797270c0e229c07be02ad3.zip |
staging: rt2860sta and rt2870sta: Remove drivers replaced in net/wireless
The staging driver rt2860sta is replaced by mainline driver rt2800pci, and
rt2870sta is replaced by rt2800usb. As a result, the staging drivers are
deleted.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
Diffstat (limited to 'drivers/staging/rt2860/common/cmm_wpa.c')
-rw-r--r-- | drivers/staging/rt2860/common/cmm_wpa.c | 3010 |
1 files changed, 0 insertions, 3010 deletions
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c deleted file mode 100644 index 616ebec50c61..000000000000 --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ /dev/null @@ -1,3010 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - wpa.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan Lee 03-07-22 Initial - Paul Lin 03-11-28 Modify for supplicant -*/ -#include "../rt_config.h" -/* WPA OUI */ -u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 }; -u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 }; -u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 }; -u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 }; -u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 }; -u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 }; - -/* WPA2 OUI */ -u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 }; -u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 }; -u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 }; - -static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 keyDescVer, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_LEN, struct rt_eapol_packet * pMsg); - -static void CalculateMIC(u8 KeyDescVer, - u8 * PTK, struct rt_eapol_packet * pMsg); - -static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, - struct rt_mlme_queue_elem *Elem); - -static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - ========================================================================== - */ -void WpaStateMachineInit(struct rt_rtmp_adapter *pAd, - struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE, - MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK, - WPA_MACHINE_BASE); - - StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, - (STATE_MACHINE_FUNC) WpaEAPPacketAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, - (STATE_MACHINE_FUNC) WpaEAPOLStartAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, - (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, - (STATE_MACHINE_FUNC) WpaEAPOLKeyAction); - StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, - (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction); -} - -/* - ========================================================================== - Description: - this is state machine function. - When receiving EAP packets which is for 802.1x authentication use. - Not use in PSK case - Return: - ========================================================================== -*/ -void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ -} - -/* - ========================================================================== - Description: - Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c - Return: - ========================================================================== -*/ -void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mac_table_entry *pEntry; - struct rt_header_802_11 * pHeader; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n")); - - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */ - if (Elem->MsgLen == 6) - pEntry = MacTableLookup(pAd, Elem->Msg); - else { - pEntry = MacTableLookup(pAd, pHeader->Addr2); - } - - if (pEntry) { - DBGPRINT(RT_DEBUG_TRACE, - (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", - pEntry->PortSecured, pEntry->WpaState, - pEntry->AuthMode, pEntry->PMKID_CacheIdx)); - - if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) - && (pEntry->WpaState < AS_PTKSTART) - && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) - || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) - || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) - && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) { - pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; - pEntry->WpaState = AS_INITPSK; - pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; - NdisZeroMemory(pEntry->R_Counter, - sizeof(pEntry->R_Counter)); - pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; - - WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); - } - } -} - -/* - ========================================================================== - Description: - This is state machine function. - When receiving EAPOL packets which is for 802.1x key management. - Use both in WPA, and WPAPSK case. - In this function, further dispatch to different functions according to the received packet. 3 categories are : - 1. normal 4-way pairwisekey and 2-way groupkey handshake - 2. MIC error (Countermeasures attack) report packet from STA. - 3. Request for pairwise/group key update from STA - Return: - ========================================================================== -*/ -void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) -{ - struct rt_mac_table_entry *pEntry; - struct rt_header_802_11 * pHeader; - struct rt_eapol_packet * pEapol_packet; - struct rt_key_info peerKeyInfo; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n")); - - pHeader = (struct rt_header_802_11 *) Elem->Msg; - pEapol_packet = - (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((u8 *)& peerKeyInfo, - (u8 *)& pEapol_packet->KeyDesc.KeyInfo, - sizeof(struct rt_key_info)); - - hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, - (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)); - - *((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo)); - - do { - pEntry = MacTableLookup(pAd, pHeader->Addr2); - - if (!pEntry - || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - break; - - if (pEntry->AuthMode < Ndis802_11AuthModeWPA) - break; - - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPoL-Key frame from STA %pMF\n", - pEntry->Addr)); - - if (((pEapol_packet->ProVer != EAPOL_VER) - && (pEapol_packet->ProVer != EAPOL_VER2)) - || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) - && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter does not match with WPA rule\n")); - break; - } - /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */ - /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */ - if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) - && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter version not match(TKIP) \n")); - break; - } - /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */ - /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */ - else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) - && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) { - DBGPRINT(RT_DEBUG_ERROR, - ("Key descripter version not match(AES) \n")); - break; - } - /* Check if this STA is in class 3 state and the WPA state is started */ - if ((pEntry->Sst == SST_ASSOC) - && (pEntry->WpaState >= AS_INITPSK)) { - /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */ - /* or not. */ - /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */ - /* Key frame from the Authenticator must not have the Ack bit set. */ - if (peerKeyInfo.KeyAck == 1) { - /* The frame is snet by Authenticator. */ - /* So the Supplicant side shall handle this. */ - - if ((peerKeyInfo.Secure == 0) - && (peerKeyInfo.Request == 0) - && (peerKeyInfo.Error == 0) - && (peerKeyInfo.KeyType == PAIRWISEKEY)) { - /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */ - /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */ - /* 2. the message 3 of 4-way HS in WPA */ - /* EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */ - if (peerKeyInfo.KeyMic == 0) - PeerPairMsg1Action(pAd, pEntry, - Elem); - else - PeerPairMsg3Action(pAd, pEntry, - Elem); - } else if ((peerKeyInfo.Secure == 1) - && (peerKeyInfo.KeyMic == 1) - && (peerKeyInfo.Request == 0) - && (peerKeyInfo.Error == 0)) { - /* Process 1. the message 3 of 4-way HS in WPA2 */ - /* EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */ - /* 2. the message 1 of group KS in WPA or WPA2 */ - /* EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */ - if (peerKeyInfo.KeyType == PAIRWISEKEY) - PeerPairMsg3Action(pAd, pEntry, - Elem); - else - PeerGroupMsg1Action(pAd, pEntry, - Elem); - } - } else { - /* The frame is snet by Supplicant. */ - /* So the Authenticator side shall handle this. */ - if ((peerKeyInfo.Request == 0) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.KeyMic == 1)) { - if (peerKeyInfo.Secure == 0 - && peerKeyInfo.KeyType == - PAIRWISEKEY) { - /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */ - /* Process 1. message 2 of 4-way HS in WPA or WPA2 */ - /* 2. message 4 of 4-way HS in WPA */ - if (CONV_ARRARY_TO_u16 - (pEapol_packet->KeyDesc. - KeyDataLen) == 0) { - PeerPairMsg4Action(pAd, - pEntry, - Elem); - } else { - PeerPairMsg2Action(pAd, - pEntry, - Elem); - } - } else if (peerKeyInfo.Secure == 1 - && peerKeyInfo.KeyType == - PAIRWISEKEY) { - /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */ - /* Process message 4 of 4-way HS in WPA2 */ - PeerPairMsg4Action(pAd, pEntry, - Elem); - } else if (peerKeyInfo.Secure == 1 - && peerKeyInfo.KeyType == - GROUPKEY) { - /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */ - /* Process message 2 of Group key HS in WPA or WPA2 */ - PeerGroupMsg2Action(pAd, pEntry, - &Elem-> - Msg - [LENGTH_802_11], - (Elem-> - MsgLen - - LENGTH_802_11)); - } - } - } - } - } while (FALSE); -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware encryption before really - sent out to air. - - Arguments: - pAd Pointer to our adapter - void * Pointer to outgoing Ndis frame - NumberOfFrag Number of fragment required - - Return Value: - None - - Note: - - ======================================================================== -*/ -void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pHeader802_3, - u32 HdrLen, - u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame) -{ - void *pPacket; - int Status; - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - do { - /* build a NDIS packet */ - Status = - RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, - pData, DataLen); - if (Status != NDIS_STATUS_SUCCESS) - break; - - if (bClearFrame) - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1); - else - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0); - { - RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); - - RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); /* set a default value */ - if (pEntry->apidx != 0) - RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, - pEntry-> - apidx); - - RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid); - RTMP_SET_PACKET_MOREDATA(pPacket, FALSE); - } - - { - /* send out the packet */ - Status = STASendPacket(pAd, pPacket); - if (Status == NDIS_STATUS_SUCCESS) { - u8 Index; - - /* Dequeue one frame from TxSwQueue0..3 queue and process it */ - /* There are three place calling dequeue for TX ring. */ - /* 1. Here, right after queueing the frame. */ - /* 2. At the end of TxRingTxDone service routine. */ - /* 3. Upon NDIS call RTMPSendPackets */ - if ((!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - && - (!RTMP_TEST_FLAG - (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) { - for (Index = 0; Index < 5; Index++) - if (pAd->TxSwQueue[Index]. - Number > 0) - RTMPDeQueuePacket(pAd, - FALSE, - Index, - MAX_TX_PROCESS); - } - } - } - - } while (FALSE); -} - -/* - ========================================================================== - Description: - This is a function to initialize 4-way handshake - - Return: - - ========================================================================== -*/ -void WPAStart4WayHS(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, unsigned long TimeInterval) -{ - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - u8 *pBssid = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n")); - - if (RTMP_TEST_FLAG - (pAd, - fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS)) - { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : The interface is closed...\n")); - return; - } - - if (pBssid == NULL) { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n")); - return; - } - /* Check the status */ - if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) { - DBGPRINT(RT_DEBUG_ERROR, - ("[ERROR]WPAStart4WayHS : Not expect calling\n")); - return; - } - - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Randomly generate ANonce */ - GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce); - - /* Construct EAPoL message - Pairwise Msg 1 */ - /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0, /* Default key index */ - pEntry->ANonce, NULL, /* TxRSC */ - NULL, /* GTK */ - NULL, /* RSNIE */ - 0, /* RSNIE length */ - &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, Header802_3, - LENGTH_802_3, (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - (pEntry->PortSecured == - WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); - - /* Trigger Retry Timer */ - RTMPModTimer(&pEntry->RetryTimer, TimeInterval); - - /* Update State */ - pEntry->WpaState = AS_PTKSTART; - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== WPAStart4WayHS: send Msg1 of 4-way \n")); - -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2 - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 PTK[80]; - u8 Header802_3[14]; - struct rt_eapol_packet * pMsg1; - u32 MsgLen; - struct rt_eapol_packet EAPOLPKT; - u8 *pCurrentAddr = NULL; - u8 *pmk_ptr = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *rsnie_ptr = NULL; - u8 rsnie_len = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - pmk_ptr = pAd->StaCfg.PMK; - group_cipher = pAd->StaCfg.GroupCipher; - rsnie_ptr = pAd->StaCfg.RSN_IE; - rsnie_len = pAd->StaCfg.RSNIE_Len; - } - - /* Store the received frame */ - pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 1 - Replay Counter */ - if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) - == FALSE) - return; - - /* Store Replay counter, it will use to verify message 3 and construct message 2 */ - NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Store ANonce */ - NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, - LEN_KEY_DESC_NONCE); - - /* Generate random SNonce */ - GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce); - - { - /* Calculate PTK(ANonce, SNonce) */ - WpaDerivePTK(pAd, - pmk_ptr, - pEntry->ANonce, - pEntry->Addr, - pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK); - - /* Save key to PTK entry */ - NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); - } - - /* Update WpaState */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - - /* Construct EAPoL message - Pairwise Msg 2 */ - /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0, /* DefaultKeyIdx */ - pEntry->SNonce, NULL, /* TxRsc */ - NULL, /* GTK */ - (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n")); -} - -/* - ========================================================================== - Description: - When receiving the second packet of 4-way pairwisekey handshake. - Return: - ========================================================================== -*/ -void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 PTK[80]; - BOOLEAN Cancelled; - struct rt_header_802_11 * pHeader; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pMsg2; - u32 MsgLen; - u8 Header802_3[LENGTH_802_3]; - u8 TxTsc[6]; - u8 *pBssid = NULL; - u8 *pmk_ptr = NULL; - u8 *gtk_ptr = NULL; - u8 default_key = 0; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *rsnie_ptr = NULL; - u8 rsnie_len = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n")); - - if ((!pEntry) || (!pEntry->ValidAsCLI)) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - /* check Entry in valid State */ - if (pEntry->WpaState < AS_PTKSTART) - return; - - /* pointer to 802.11 header */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /* skip 802.11_header(24-byte) and LLC_header(8) */ - pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Store SNonce */ - NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, - LEN_KEY_DESC_NONCE); - - { - /* Derive PTK */ - WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce, /* ANONCE */ - (u8 *) pBssid, pEntry->SNonce, /* SNONCE */ - pEntry->Addr, PTK, LEN_PTK); - - NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); - } - - /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) - == FALSE) - return; - - do { - /* delete retry timer */ - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* Change state */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Construct EAPoL message - Pairwise Msg 3 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, - group_cipher, - EAPOL_PAIR_MSG_3, - default_key, - pEntry->ANonce, - TxTsc, - (u8 *) gtk_ptr, - (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - (pEntry->PortSecured == - WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); - - pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR; - RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); - - /* Update State */ - pEntry->WpaState = AS_PTKINIT_NEGOTIATING; - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n")); -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4 - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - struct rt_header_802_11 * pHeader; - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pMsg3; - u32 MsgLen; - u8 *pCurrentAddr = NULL; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - group_cipher = pAd->StaCfg.GroupCipher; - - } - - /* Record 802.11 header & the received EAPOL packet Msg3 */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) - == FALSE) - return; - - /* Save Replay counter, it will use construct message 4 */ - NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Double check ANonce */ - if (!NdisEqualMemory - (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) { - return; - } - /* Construct EAPoL message - Pairwise Msg 4 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0, /* group key index not used in message 4 */ - NULL, /* Nonce not used in message 4 */ - NULL, /* TxRSC not used in message 4 */ - NULL, /* GTK not used in message 4 */ - NULL, /* RSN IE not used in message 4 */ - 0, &EAPOLPKT); - - /* Update WpaState */ - pEntry->WpaState = AS_PTKINITDONE; - - /* Update pairwise key */ - { - struct rt_cipher_key *pSharedKey; - - pSharedKey = &pAd->SharedKey[BSS0][0]; - - NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], - LEN_TKIP_TXMICK); - - /* Decide its ChiperAlg */ - if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else - pSharedKey->CipherAlg = CIPHER_NONE; - - /* Update these related information to struct rt_mac_table_entry */ - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], - LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; - - /* Update pairwise key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - 0, pSharedKey->CipherAlg, pEntry); - - } - - /* open 802.1x port control and privacy filter */ - if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK || - pEntry->AuthMode == Ndis802_11AuthModeWPA2) { - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - - STA_PORT_SECURED(pAd); - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = NdisMediaStateConnected; - DBGPRINT(RT_DEBUG_TRACE, - ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", - GetAuthMode(pEntry->AuthMode), - GetEncryptType(pEntry->WepStatus), - GetEncryptType(group_cipher))); - } else { - } - - /* Init 802.3 header and send out */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n")); -} - -/* - ========================================================================== - Description: - When receiving the last packet of 4-way pairwisekey handshake. - Initialize 2-way groupkey handshake following. - Return: - ========================================================================== -*/ -void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - struct rt_eapol_packet * pMsg4; - struct rt_header_802_11 * pHeader; - u32 MsgLen; - BOOLEAN Cancelled; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n")); - - do { - if ((!pEntry) || (!pEntry->ValidAsCLI)) - break; - - if (Elem->MsgLen < - (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + - sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2)) - break; - - if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING) - break; - - /* pointer to 802.11 header */ - pHeader = (struct rt_header_802_11 *) Elem->Msg; - - /* skip 802.11_header(24-byte) and LLC_header(8) */ - pMsg4 = - (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */ - if (PeerWpaMessageSanity - (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE) - break; - - /* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */ - NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key)); - - /* reset IVEIV in Asic */ - AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0); - - pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], - LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, - &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], - LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, - &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], - LEN_TKIP_TXMICK); - - /* Set pairwise key to Asic */ - { - pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) - pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; - else if (pEntry->WepStatus == - Ndis802_11Encryption3Enabled) - pEntry->PairwiseKey.CipherAlg = CIPHER_AES; - - /* Add Pair-wise key to Asic */ - AsicAddPairwiseKeyEntry(pAd, - pEntry->Addr, - (u8)pEntry->Aid, - &pEntry->PairwiseKey); - - /* update WCID attribute table and IVEIV table for this entry */ - RTMPAddWcidAttributeEntry(pAd, - pEntry->apidx, - 0, - pEntry->PairwiseKey.CipherAlg, - pEntry); - } - - /* 4. upgrade state */ - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - pEntry->WpaState = AS_PTKINITDONE; - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - - if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 || - pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) { - pEntry->GTKState = REKEY_ESTABLISHED; - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* send wireless event - for set key done WPA2 */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA2_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } else { - /* 5. init Group 2-way handshake if necessary. */ - WPAStart2WayGroupHS(pAd, pEntry); - - pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR; - RTMPModTimer(&pEntry->RetryTimer, - PEER_MSG3_RETRY_EXEC_INTV); - } - } while (FALSE); - -} - -/* - ========================================================================== - Description: - This is a function to send the first packet of 2-way groupkey handshake - Return: - - ========================================================================== -*/ -void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry) -{ - u8 Header802_3[14]; - u8 TxTsc[6]; - struct rt_eapol_packet EAPOLPKT; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 default_key = 0; - u8 *gnonce_ptr = NULL; - u8 *gtk_ptr = NULL; - u8 *pBssid = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n")); - - if ((!pEntry) || (!pEntry->ValidAsCLI)) - return; - - do { - /* Increment replay counter by 1 */ - ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); - - /* Construct EAPoL message - Group Msg 1 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, - group_cipher, - EAPOL_GROUP_MSG_1, - default_key, - (u8 *) gnonce_ptr, - TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT); - - /* Make outgoing frame */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, LENGTH_802_3, - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, - FALSE); - - } while (FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n")); - - return; -} - -/* - ======================================================================== - - Routine Description: - Process Group key 2-way handshaking - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem) -{ - u8 Header802_3[14]; - struct rt_eapol_packet EAPOLPKT; - struct rt_eapol_packet * pGroup; - u32 MsgLen; - BOOLEAN Cancelled; - u8 default_key = 0; - u8 group_cipher = Ndis802_11WEPDisabled; - u8 *pCurrentAddr = NULL; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n")); - - if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) - return; - - { - pCurrentAddr = pAd->CurrentAddress; - group_cipher = pAd->StaCfg.GroupCipher; - default_key = pAd->StaCfg.DefaultKeyId; - } - - /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */ - pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; - - /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */ - if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) - == FALSE) - return; - - /* delete retry timer */ - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - - /* Save Replay counter, it will use to construct message 2 */ - NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, - LEN_KEY_DESC_REPLAY); - - /* Construct EAPoL message - Group Msg 2 */ - NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet)); - ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL, /* Nonce not used */ - NULL, /* TxRSC not used */ - NULL, /* GTK not used */ - NULL, /* RSN IE not used */ - 0, &EAPOLPKT); - - /* open 802.1x port control and privacy filter */ - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; - - STA_PORT_SECURED(pAd); - /* Indicate Connected for GUI */ - pAd->IndicateMediaState = NdisMediaStateConnected; - - DBGPRINT(RT_DEBUG_TRACE, - ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", - GetAuthMode(pEntry->AuthMode), - GetEncryptType(pEntry->WepStatus), - GetEncryptType(group_cipher))); - - /* init header and Fill Packet and send Msg 2 to authenticator */ - MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); - RTMPToWirelessSta(pAd, pEntry, - Header802_3, sizeof(Header802_3), - (u8 *)& EAPOLPKT, - CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE); - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== PeerGroupMsg1Action: sned group message 2\n")); -} - -/* - ========================================================================== - Description: - When receiving the last packet of 2-way groupkey handshake. - Return: - ========================================================================== -*/ -void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - void * Msg, u32 MsgLen) -{ - u32 Len; - u8 *pData; - BOOLEAN Cancelled; - struct rt_eapol_packet * pMsg2; - u8 group_cipher = Ndis802_11WEPDisabled; - - DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n")); - - do { - if ((!pEntry) || (!pEntry->ValidAsCLI)) - break; - - if (MsgLen < - (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) - - MAX_LEN_OF_RSNIE - 2)) - break; - - if (pEntry->WpaState != AS_PTKINITDONE) - break; - - pData = (u8 *)Msg; - pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H); - Len = MsgLen - LENGTH_802_1_H; - - /* Sanity Check peer group message 2 - Replay Counter, MIC */ - if (PeerWpaMessageSanity - (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE) - break; - - /* 3. upgrade state */ - - RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); - pEntry->GTKState = REKEY_ESTABLISHED; - - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) - || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { - /* send wireless event - for set key done WPA2 */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA2_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } else { - /* send wireless event - for set key done WPA */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_SET_KEY_DONE_WPA1_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_OFF, - ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", - pEntry->AuthMode, - GetAuthMode(pEntry->AuthMode), - pEntry->WepStatus, - GetEncryptType(pEntry->WepStatus), - group_cipher, GetEncryptType(group_cipher))); - } - } while (FALSE); -} - -/* - ======================================================================== - - Routine Description: - Classify WPA EAP message type - - Arguments: - EAPType Value of EAP message type - MsgType Internal Message definition for MLME state machine - - Return Value: - TRUE Found appropriate message type - FALSE No appropriate message type - - IRQL = DISPATCH_LEVEL - - Note: - All these constants are defined in wpa.h - For supplicant, there is only EAPOL Key message available - - ======================================================================== -*/ -BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType) -{ - switch (EAPType) { - case EAPPacket: - *MsgType = MT2_EAPPacket; - break; - case EAPOLStart: - *MsgType = MT2_EAPOLStart; - break; - case EAPOLLogoff: - *MsgType = MT2_EAPOLLogoff; - break; - case EAPOLKey: - *MsgType = MT2_EAPOLKey; - break; - case EAPOLASFAlert: - *MsgType = MT2_EAPOLASFAlert; - break; - default: - return FALSE; - } - return TRUE; -} - -/* - ======================================================================== - - Routine Description: - The pseudo-random function(PRF) that hashes various inputs to - derive a pseudo-random value. To add liveness to the pseudo-random - value, a nonce should be one of the inputs. - - It is used to generate PTK, GTK or some specific random value. - - Arguments: - u8 *key, - the key material for HMAC_SHA1 use - int key_len - the length of key - u8 *prefix - a prefix label - int prefix_len - the length of the label - u8 *data - a specific data with variable length - int data_len - the length of a specific data - int len - the output length - - Return Value: - u8 *output - the calculated result - - Note: - 802.11i-2004 Annex H.3 - - ======================================================================== -*/ -void PRF(u8 * key, - int key_len, - u8 * prefix, - int prefix_len, - u8 * data, int data_len, u8 * output, int len) -{ - int i; - u8 *input; - int currentindex = 0; - int total_len; - - /* Allocate memory for input */ - os_alloc_mem(NULL, (u8 **) & input, 1024); - - if (input == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n")); - return; - } - /* Generate concatenation input */ - NdisMoveMemory(input, prefix, prefix_len); - - /* Concatenate a single octet containing 0 */ - input[prefix_len] = 0; - - /* Concatenate specific data */ - NdisMoveMemory(&input[prefix_len + 1], data, data_len); - total_len = prefix_len + 1 + data_len; - - /* Concatenate a single octet containing 0 */ - /* This octet shall be update later */ - input[total_len] = 0; - total_len++; - - /* Iterate to calculate the result by hmac-sha-1 */ - /* Then concatenate to last result */ - for (i = 0; i < (len + 19) / 20; i++) { - HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], - SHA1_DIGEST_SIZE); - currentindex += 20; - - /* update the last octet */ - input[total_len - 1]++; - } - os_free_mem(NULL, input); -} - -/* -* F(P, S, c, i) = U1 xor U2 xor ... Uc -* U1 = PRF(P, S || Int(i)) -* U2 = PRF(P, U1) -* Uc = PRF(P, Uc-1) -*/ - -static void F(char *password, unsigned char *ssid, int ssidlength, - int iterations, int count, unsigned char *output) -{ - unsigned char digest[36], digest1[SHA1_DIGEST_SIZE]; - int i, j; - - /* U1 = PRF(P, S || int(i)) */ - memcpy(digest, ssid, ssidlength); - digest[ssidlength] = (unsigned char)((count >> 24) & 0xff); - digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff); - digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff); - digest[ssidlength + 3] = (unsigned char)(count & 0xff); - HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE); /* for WPA update */ - - /* output = U1 */ - memcpy(output, digest1, SHA1_DIGEST_SIZE); - - for (i = 1; i < iterations; i++) { - /* Un = PRF(P, Un-1) */ - HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); /* for WPA update */ - memcpy(digest1, digest, SHA1_DIGEST_SIZE); - - /* output = output xor Un */ - for (j = 0; j < SHA1_DIGEST_SIZE; j++) { - output[j] ^= digest[j]; - } - } -} - -/* -* password - ascii string up to 63 characters in length -* ssid - octet string up to 32 octets -* ssidlength - length of ssid in octets -* output must be 40 octets in length and outputs 256 bits of key -*/ -int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output) -{ - if ((strlen(password) > 63) || (ssidlength > 32)) - return 0; - - F(password, ssid, ssidlength, 4096, 1, output); - F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]); - return 1; -} - -/* - ======================================================================== - - Routine Description: - It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. - It shall be called by 4-way handshake processing. - - Arguments: - pAd - pointer to our pAdapter context - PMK - pointer to PMK - ANonce - pointer to ANonce - AA - pointer to Authenticator Address - SNonce - pointer to SNonce - SA - pointer to Supplicant Address - len - indicate the length of PTK (octet) - - Return Value: - Output pointer to the PTK - - Note: - Refer to IEEE 802.11i-2004 8.5.1.2 - - ======================================================================== -*/ -void WpaDerivePTK(struct rt_rtmp_adapter *pAd, - u8 * PMK, - u8 * ANonce, - u8 * AA, - u8 * SNonce, - u8 * SA, u8 * output, u32 len) -{ - u8 concatenation[76]; - u32 CurrPos = 0; - u8 temp[32]; - u8 Prefix[] = - { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', - 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n' - }; - - /* initiate the concatenation input */ - NdisZeroMemory(temp, sizeof(temp)); - NdisZeroMemory(concatenation, 76); - - /* Get smaller address */ - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(concatenation, AA, 6); - else - NdisMoveMemory(concatenation, SA, 6); - CurrPos += 6; - - /* Get larger address */ - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(&concatenation[CurrPos], SA, 6); - else - NdisMoveMemory(&concatenation[CurrPos], AA, 6); - - /* store the larger mac address for backward compatible of */ - /* ralink proprietary STA-key issue */ - NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); - CurrPos += 6; - - /* Get smaller Nonce */ - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */ - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); - else - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - CurrPos += 32; - - /* Get larger Nonce */ - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); /* patch for ralink proprietary STA-key issue */ - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - else - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); - CurrPos += 32; - - hex_dump("concatenation=", concatenation, 76); - - /* Use PRF to generate PTK */ - PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len); - -} - -/* - ======================================================================== - - Routine Description: - Generate random number by software. - - Arguments: - pAd - pointer to our pAdapter context - macAddr - pointer to local MAC address - - Return Value: - - Note: - 802.1ii-2004 Annex H.5 - - ======================================================================== -*/ -void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random) -{ - int i, curr; - u8 local[80], KeyCounter[32]; - u8 result[80]; - unsigned long CurrentTime; - u8 prefix[] = - { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' }; - - /* Zero the related information */ - NdisZeroMemory(result, 80); - NdisZeroMemory(local, 80); - NdisZeroMemory(KeyCounter, 32); - - for (i = 0; i < 32; i++) { - /* copy the local MAC address */ - COPY_MAC_ADDR(local, macAddr); - curr = MAC_ADDR_LEN; - - /* concatenate the current time */ - NdisGetSystemUpTime(&CurrentTime); - NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); - curr += sizeof(CurrentTime); - - /* concatenate the last result */ - NdisMoveMemory(&local[curr], result, 32); - curr += 32; - - /* concatenate a variable */ - NdisMoveMemory(&local[curr], &i, 2); - curr += 2; - - /* calculate the result */ - PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32); - } - - NdisMoveMemory(random, result, 32); -} - -/* - ======================================================================== - - Routine Description: - Build cipher suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - WepStatus - indicate the encryption type - bMixCipher - a boolean to indicate the pairwise cipher and group - cipher are the same or not - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u32 WepStatus, - IN BOOLEAN bMixCipher, - u8 FlexibleCipher, - u8 *pRsnIe, u8 * rsn_len) -{ - u8 PairwiseCnt; - - *rsn_len = 0; - - /* decide WPA2 or WPA1 */ - if (ElementID == Wpa2Ie) { - struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe; - - /* Assign the verson as 1 */ - pRsnie_cipher->version = 1; - - switch (WepStatus) { - /* TKIP mode */ - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_TKIP, 4); - *rsn_len = sizeof(struct rt_rsnie2); - break; - - /* AES mode */ - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_TKIP, 4); - else - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_CCMP, 4); - *rsn_len = sizeof(struct rt_rsnie2); - break; - - /* TKIP-AES mix mode */ - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); - - PairwiseCnt = 1; - /* Insert WPA2 TKIP as the first pairwise cipher */ - if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_TKIP, 4); - /* Insert WPA2 AES as the secondary pairwise cipher */ - if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0]. - oui + 4, OUI_WPA2_CCMP, - 4); - PairwiseCnt = 2; - } - } else { - /* Insert WPA2 AES as the first pairwise cipher */ - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA2_CCMP, 4); - } - - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1)); - break; - } - - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) { - u32 GroupCipher = pAd->StaCfg.GroupCipher; - switch (GroupCipher) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA2_WEP104, 4); - break; - } - } - /* swap for big-endian platform */ - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); - } else { - struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe; - - /* Assign OUI and version */ - NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4); - pRsnie_cipher->version = 1; - - switch (WepStatus) { - /* TKIP mode */ - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_TKIP, 4); - *rsn_len = sizeof(struct rt_rsnie); - break; - - /* AES mode */ - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_TKIP, 4); - else - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_CCMP, 4); - *rsn_len = sizeof(struct rt_rsnie); - break; - - /* TKIP-AES mix mode */ - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - - PairwiseCnt = 1; - /* Insert WPA TKIP as the first pairwise cipher */ - if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_TKIP, 4); - /* Insert WPA AES as the secondary pairwise cipher */ - if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) { - NdisMoveMemory(pRsnie_cipher->ucast[0]. - oui + 4, OUI_WPA_CCMP, - 4); - PairwiseCnt = 2; - } - } else { - /* Insert WPA AES as the first pairwise cipher */ - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, - OUI_WPA_CCMP, 4); - } - - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1)); - break; - } - - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) { - u32 GroupCipher = pAd->StaCfg.GroupCipher; - switch (GroupCipher) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, - OUI_WPA_WEP104, 4); - break; - } - } - /* swap for big-endian platform */ - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); - } -} - -/* - ======================================================================== - - Routine Description: - Build AKM suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - AuthMode - indicate the authentication mode - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u32 AuthMode, - u8 apidx, - u8 *pRsnIe, u8 * rsn_len) -{ - struct rt_rsnie_auth *pRsnie_auth; - u8 AkmCnt = 1; /* default as 1 */ - - pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len)); - - /* decide WPA2 or WPA1 */ - if (ElementID == Wpa2Ie) { - - switch (AuthMode) { - case Ndis802_11AuthModeWPA2: - case Ndis802_11AuthModeWPA1WPA2: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA2_8021X_AKM, 4); - break; - - case Ndis802_11AuthModeWPA2PSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA2_PSK_AKM, 4); - break; - default: - AkmCnt = 0; - break; - - } - } else { - switch (AuthMode) { - case Ndis802_11AuthModeWPA: - case Ndis802_11AuthModeWPA1WPA2: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_8021X_AKM, 4); - break; - - case Ndis802_11AuthModeWPAPSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_PSK_AKM, 4); - break; - - case Ndis802_11AuthModeWPANone: - NdisMoveMemory(pRsnie_auth->auth[0].oui, - OUI_WPA_NONE_AKM, 4); - break; - default: - AkmCnt = 0; - break; - } - } - - pRsnie_auth->acount = AkmCnt; - pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); - - /* update current RSNIE length */ - (*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1))); - -} - -/* - ======================================================================== - - Routine Description: - Build capability in RSN-IE. - It only shall be called by RTMPMakeRSNIE. - - Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd, - u8 ElementID, - u8 apidx, - u8 *pRsnIe, u8 * rsn_len) -{ - RSN_CAPABILITIES *pRSN_Cap; - - /* it could be ignored in WPA1 mode */ - if (ElementID == WpaIe) - return; - - pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len)); - - pRSN_Cap->word = cpu2le16(pRSN_Cap->word); - - (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */ - -} - -/* - ======================================================================== - - Routine Description: - Build RSN IE context. It is not included element-ID and length. - - Arguments: - pAd - pointer to our pAdapter context - AuthMode - indicate the authentication mode - WepStatus - indicate the encryption type - apidx - indicate the interface index - - Return Value: - - Note: - - ======================================================================== -*/ -void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd, - u32 AuthMode, u32 WepStatus, u8 apidx) -{ - u8 *pRsnIe = NULL; /* primary RSNIE */ - u8 *rsnielen_cur_p = 0; /* the length of the primary RSNIE */ - u8 *rsnielen_ex_cur_p = 0; /* the length of the secondary RSNIE */ - u8 PrimaryRsnie; - BOOLEAN bMixCipher = FALSE; /* indicate the pairwise and group cipher are different */ - u8 p_offset; - WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */ - - rsnielen_cur_p = NULL; - rsnielen_ex_cur_p = NULL; - - { - { - if (pAd->StaCfg.WpaSupplicantUP != - WPA_SUPPLICANT_DISABLE) { - if (AuthMode < Ndis802_11AuthModeWPA) - return; - } else { - /* Support WPAPSK or WPA2PSK in STA-Infra mode */ - /* Support WPANone in STA-Adhoc mode */ - if ((AuthMode != Ndis802_11AuthModeWPAPSK) && - (AuthMode != Ndis802_11AuthModeWPA2PSK) && - (AuthMode != Ndis802_11AuthModeWPANone) - ) - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n")); - - /* Zero RSNIE context */ - pAd->StaCfg.RSNIE_Len = 0; - NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE); - - /* Pointer to RSNIE */ - rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len; - pRsnIe = pAd->StaCfg.RSN_IE; - - bMixCipher = pAd->StaCfg.bMixCipher; - } - } - - /* indicate primary RSNIE as WPA or WPA2 */ - if ((AuthMode == Ndis802_11AuthModeWPA) || - (AuthMode == Ndis802_11AuthModeWPAPSK) || - (AuthMode == Ndis802_11AuthModeWPANone) || - (AuthMode == Ndis802_11AuthModeWPA1WPA2) || - (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) - PrimaryRsnie = WpaIe; - else - PrimaryRsnie = Wpa2Ie; - - { - /* Build the primary RSNIE */ - /* 1. insert cipher suite */ - RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, - FlexibleCipher, pRsnIe, &p_offset); - - /* 2. insert AKM */ - RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, - &p_offset); - - /* 3. insert capability */ - RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); - } - - /* 4. update the RSNIE length */ - *rsnielen_cur_p = p_offset; - - hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p)); - -} - -/* - ========================================================================== - Description: - Check whether the received frame is EAP frame. - - Arguments: - pAd - pointer to our pAdapter context - pEntry - pointer to active entry - pData - the received frame - DataByteCount - the received frame's length - FromWhichBSSID - indicate the interface index - - Return: - TRUE - This frame is EAP frame - FALSE - otherwise - ========================================================================== -*/ -BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd, - struct rt_mac_table_entry *pEntry, - u8 *pData, - unsigned long DataByteCount, u8 FromWhichBSSID) -{ - unsigned long Body_len; - BOOLEAN Cancelled; - - if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H)) - return FALSE; - - /* Skip LLC header */ - if (NdisEqualMemory(SNAP_802_1H, pData, 6) || - /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */ - NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) { - pData += 6; - } - /* Skip 2-bytes EAPoL type */ - if (NdisEqualMemory(EAPOL, pData, 2)) { - pData += 2; - } else - return FALSE; - - switch (*(pData + 1)) { - case EAPPacket: - Body_len = (*(pData + 2) << 8) | (*(pData + 3)); - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", - Body_len)); - break; - case EAPOLStart: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOL-Start frame, TYPE = 1 \n")); - if (pEntry->EnqueueEapolStartTimerRunning != - EAPOL_START_DISABLE) { - DBGPRINT(RT_DEBUG_TRACE, - ("Cancel the EnqueueEapolStartTimerRunning \n")); - RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, - &Cancelled); - pEntry->EnqueueEapolStartTimerRunning = - EAPOL_START_DISABLE; - } - break; - case EAPOLLogoff: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOLLogoff frame, TYPE = 2 \n")); - break; - case EAPOLKey: - Body_len = (*(pData + 2) << 8) | (*(pData + 3)); - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", - Body_len)); - break; - case EAPOLASFAlert: - DBGPRINT(RT_DEBUG_TRACE, - ("Receive EAPOLASFAlert frame, TYPE = 4 \n")); - break; - default: - return FALSE; - - } - return TRUE; -} - -/* - ========================================================================== - Description: - Report the EAP message type - - Arguments: - msg - EAPOL_PAIR_MSG_1 - EAPOL_PAIR_MSG_2 - EAPOL_PAIR_MSG_3 - EAPOL_PAIR_MSG_4 - EAPOL_GROUP_MSG_1 - EAPOL_GROUP_MSG_2 - - Return: - message type string - - ========================================================================== -*/ -char *GetEapolMsgType(char msg) -{ - if (msg == EAPOL_PAIR_MSG_1) - return "Pairwise Message 1"; - else if (msg == EAPOL_PAIR_MSG_2) - return "Pairwise Message 2"; - else if (msg == EAPOL_PAIR_MSG_3) - return "Pairwise Message 3"; - else if (msg == EAPOL_PAIR_MSG_4) - return "Pairwise Message 4"; - else if (msg == EAPOL_GROUP_MSG_1) - return "Group Message 1"; - else if (msg == EAPOL_GROUP_MSG_2) - return "Group Message 2"; - else - return "Invalid Message"; -} - -/* - ======================================================================== - - Routine Description: - Check Sanity RSN IE of EAPoL message - - Arguments: - - Return Value: - - ======================================================================== -*/ -BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd, - u8 *pData, - u8 DataLen, - struct rt_mac_table_entry *pEntry, u8 * Offset) -{ - u8 *pVIE; - u8 len; - struct rt_eid * pEid; - BOOLEAN result = FALSE; - - pVIE = pData; - len = DataLen; - *Offset = 0; - - while (len > sizeof(struct rt_rsnie2)) { - pEid = (struct rt_eid *) pVIE; - /* WPA RSN IE */ - if ((pEid->Eid == IE_WPA) - && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) { - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA - || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) - && - (NdisEqualMemory - (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) - && (pEntry->RSNIE_Len == (pEid->Len + 2))) { - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } - /* WPA2 RSN IE */ - else if ((pEid->Eid == IE_RSN) - && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) { - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 - || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) - && (pEid->Eid == pEntry->RSN_IE[0]) - && ((pEid->Len + 2) >= pEntry->RSNIE_Len) - && - (NdisEqualMemory - (pEid->Octet, &pEntry->RSN_IE[2], - pEntry->RSNIE_Len - 2))) { - - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } else { - break; - } - - pVIE += (pEid->Len + 2); - len -= (pEid->Len + 2); - } - - return result; - -} - -/* - ======================================================================== - - Routine Description: - Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK. - GTK is encaptulated in KDE format at p.83 802.11i D10 - - Arguments: - - Return Value: - - Note: - 802.11i D10 - - ======================================================================== -*/ -BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd, - u8 *pKeyData, - u8 KeyDataLen, - u8 GroupKeyIndex, - u8 MsgType, - IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry) -{ - struct rt_kde_encap * pKDE = NULL; - u8 *pMyKeyData = pKeyData; - u8 KeyDataLength = KeyDataLen; - u8 GTKLEN = 0; - u8 DefaultIdx = 0; - u8 skip_offset; - - /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */ - if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) { - /* Check RSN IE whether it is WPA2/WPA2PSK */ - if (!RTMPCheckRSNIE - (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) { - /* send wireless event - for RSN IE different */ - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, - IW_RSNIE_DIFF_EVENT_FLAG, - pEntry->Addr, - pEntry->apidx, 0); - - DBGPRINT(RT_DEBUG_ERROR, - ("RSN_IE Different in msg %d of 4-way handshake!\n", - MsgType)); - hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen); - hex_dump("Desired RSN_IE ", pEntry->RSN_IE, - pEntry->RSNIE_Len); - - return FALSE; - } else { - if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) { - WpaShowAllsuite(pMyKeyData, skip_offset); - - /* skip RSN IE */ - pMyKeyData += skip_offset; - KeyDataLength -= skip_offset; - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", - skip_offset)); - } else - return TRUE; - } - } - - DBGPRINT(RT_DEBUG_TRACE, - ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", - KeyDataLength)); - /*hex_dump("remain data", pMyKeyData, KeyDataLength); */ - - /* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */ - if (bWPA2 - && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) { - if (KeyDataLength >= 8) /* KDE format exclude GTK length */ - { - pKDE = (struct rt_kde_encap *) pMyKeyData; - - DefaultIdx = pKDE->GTKEncap.Kid; - - /* Sanity check - KED length */ - if (KeyDataLength < (pKDE->Len + 2)) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: The len from KDE is too short \n")); - return FALSE; - } - /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */ - GTKLEN = pKDE->Len - 6; - if (GTKLEN < LEN_AES_KEY) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: GTK Key length is too short (%d) \n", - GTKLEN)); - return FALSE; - } - - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: KDE format length is too short \n")); - return FALSE; - } - - DBGPRINT(RT_DEBUG_TRACE, - ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", - DefaultIdx, GTKLEN)); - /* skip it */ - pMyKeyData += 8; - KeyDataLength -= 8; - - } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) { - DefaultIdx = GroupKeyIndex; - DBGPRINT(RT_DEBUG_TRACE, - ("GTK DefaultKeyID=%d \n", DefaultIdx)); - } - /* Sanity check - shared key index must be 1 ~ 3 */ - if (DefaultIdx < 1 || DefaultIdx > 3) { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR: GTK Key index(%d) is invalid in %s %s \n", - DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), - GetEapolMsgType(MsgType))); - return FALSE; - } - - { - struct rt_cipher_key *pSharedKey; - - /* set key material, TxMic and RxMic */ - NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32); - pAd->StaCfg.DefaultKeyId = DefaultIdx; - - pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; - - /* Prepare pair-wise key information into shared key table */ - NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key)); - pSharedKey->KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK); - NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], - LEN_TKIP_RXMICK); - NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], - LEN_TKIP_TXMICK); - - /* Update Shared Key CipherAlg */ - pSharedKey->CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) - pSharedKey->CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == - Ndis802_11Encryption3Enabled) - pSharedKey->CipherAlg = CIPHER_AES; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) - pSharedKey->CipherAlg = CIPHER_WEP64; - else if (pAd->StaCfg.GroupCipher == - Ndis802_11GroupWEP104Enabled) - pSharedKey->CipherAlg = CIPHER_WEP128; - - /* Update group key information to ASIC Shared Key Table */ - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, - pSharedKey->Key, - pSharedKey->TxMic, pSharedKey->RxMic); - - /* Update ASIC WCID attribute table and IVEIV table */ - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pSharedKey->CipherAlg, NULL); - } - - return TRUE; - -} - -/* - ======================================================================== - - Routine Description: - Construct EAPoL message for WPA handshaking - Its format is below, - - +--------------------+ - | Protocol Version | 1 octet - +--------------------+ - | Protocol Type | 1 octet - +--------------------+ - | Body Length | 2 octets - +--------------------+ - | Descriptor Type | 1 octet - +--------------------+ - | Key Information | 2 octets - +--------------------+ - | Key Length | 1 octet - +--------------------+ - | Key Repaly Counter | 8 octets - +--------------------+ - | Key Nonce | 32 octets - +--------------------+ - | Key IV | 16 octets - +--------------------+ - | Key RSC | 8 octets - +--------------------+ - | Key ID or Reserved | 8 octets - +--------------------+ - | Key MIC | 16 octets - +--------------------+ - | Key Data Length | 2 octets - +--------------------+ - | Key Data | n octets - +--------------------+ - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -void ConstructEapolMsg(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * KeyNonce, - u8 * TxRSC, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_Len, struct rt_eapol_packet * pMsg) -{ - BOOLEAN bWPA2 = FALSE; - u8 KeyDescVer; - - /* Choose WPA2 or not */ - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || - (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) - bWPA2 = TRUE; - - /* Init Packet and Fill header */ - pMsg->ProVer = EAPOL_VER; - pMsg->ProType = EAPOLKey; - - /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */ - SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG); - - /* Fill in EAPoL descriptor */ - if (bWPA2) - pMsg->KeyDesc.Type = WPA2_KEY_DESC; - else - pMsg->KeyDesc.Type = WPA1_KEY_DESC; - - /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */ - { - /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */ - /* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */ - KeyDescVer = - (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) - || (GroupKeyWepStatus == - Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) - : (DESC_TYPE_TKIP)); - } - - pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer; - - /* Specify Key Type as Group(0) or Pairwise(1) */ - if (MsgType >= EAPOL_GROUP_MSG_1) - pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY; - else - pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - /* Specify Key Index, only group_msg1_WPA1 */ - if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)) - pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx; - - if (MsgType == EAPOL_PAIR_MSG_3) - pMsg->KeyDesc.KeyInfo.Install = 1; - - if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) - || (MsgType == EAPOL_GROUP_MSG_1)) - pMsg->KeyDesc.KeyInfo.KeyAck = 1; - - if (MsgType != EAPOL_PAIR_MSG_1) - pMsg->KeyDesc.KeyInfo.KeyMic = 1; - - if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || - (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) { - pMsg->KeyDesc.KeyInfo.Secure = 1; - } - - if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || - (MsgType == EAPOL_GROUP_MSG_1))) { - pMsg->KeyDesc.KeyInfo.EKD_DL = 1; - } - /* key Information element has done. */ - *(u16 *) (&pMsg->KeyDesc.KeyInfo) = - cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo)); - - /* Fill in Key Length */ - { - if (MsgType >= EAPOL_GROUP_MSG_1) { - /* the length of group key cipher */ - pMsg->KeyDesc.KeyLength[1] = - ((GroupKeyWepStatus == - Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : - LEN_AES_KEY); - } else { - /* the length of pairwise key cipher */ - pMsg->KeyDesc.KeyLength[1] = - ((pEntry->WepStatus == - Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : - LEN_AES_KEY); - } - } - - /* Fill in replay counter */ - NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, - LEN_KEY_DESC_REPLAY); - - /* Fill Key Nonce field */ - /* ANonce : pairwise_msg1 & pairwise_msg3 */ - /* SNonce : pairwise_msg2 */ - /* GNonce : group_msg1_wpa1 */ - if ((MsgType <= EAPOL_PAIR_MSG_3) - || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)))) - NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, - LEN_KEY_DESC_NONCE); - - /* Fill key IV - WPA2 as 0, WPA1 as random */ - if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) { - /* Suggest IV be random number plus some number, */ - NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], - LEN_KEY_DESC_IV); - pMsg->KeyDesc.KeyIv[15] += 2; - } - /* Fill Key RSC field */ - /* It contains the RSC for the GTK being installed. */ - if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) - || (MsgType == EAPOL_GROUP_MSG_1)) { - NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6); - } - /* Clear Key MIC field for MIC calculation later */ - NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - - ConstructEapolKeyData(pEntry, - GroupKeyWepStatus, - KeyDescVer, - MsgType, - DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg); - - /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */ - if (MsgType != EAPOL_PAIR_MSG_1) { - CalculateMIC(KeyDescVer, pEntry->PTK, pMsg); - } - - DBGPRINT(RT_DEBUG_TRACE, - ("===> ConstructEapolMsg for %s %s\n", - ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); - DBGPRINT(RT_DEBUG_TRACE, - (" Body length = %d \n", - CONV_ARRARY_TO_u16(pMsg->Body_Len))); - DBGPRINT(RT_DEBUG_TRACE, - (" Key length = %d \n", - CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength))); - -} - -/* - ======================================================================== - - Routine Description: - Construct the Key Data field of EAPoL message - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry, - u8 GroupKeyWepStatus, - u8 keyDescVer, - u8 MsgType, - u8 DefaultKeyIdx, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_LEN, struct rt_eapol_packet * pMsg) -{ - u8 *mpool, *Key_Data, *Rc4GTK; - u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)]; - unsigned long data_offset; - BOOLEAN bWPA2Capable = FALSE; - struct rt_rtmp_adapter *pAd = pEntry->pAd; - BOOLEAN GTK_Included = FALSE; - - /* Choose WPA2 or not */ - if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || - (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) - bWPA2Capable = TRUE; - - if (MsgType == EAPOL_PAIR_MSG_1 || - MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) - return; - - /* allocate memory pool */ - os_alloc_mem(NULL, (u8 **) & mpool, 1500); - - if (mpool == NULL) - return; - - /* Rc4GTK Len = 512 */ - Rc4GTK = (u8 *) ROUND_UP(mpool, 4); - /* Key_Data Len = 512 */ - Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4); - - NdisZeroMemory(Key_Data, 512); - SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0); - data_offset = 0; - - /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */ - if (RSNIE_LEN - && ((MsgType == EAPOL_PAIR_MSG_2) - || (MsgType == EAPOL_PAIR_MSG_3))) { - u8 *pmkid_ptr = NULL; - u8 pmkid_len = 0; - - RTMPInsertRSNIE(&Key_Data[data_offset], - &data_offset, - RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len); - } - - /* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */ - if (bWPA2Capable - && ((MsgType == EAPOL_PAIR_MSG_3) - || (MsgType == EAPOL_GROUP_MSG_1))) { - /* Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h */ - Key_Data[data_offset + 0] = 0xDD; - - if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { - Key_Data[data_offset + 1] = 0x16; /* 4+2+16(OUI+DataType+DataField) */ - } else { - Key_Data[data_offset + 1] = 0x26; /* 4+2+32(OUI+DataType+DataField) */ - } - - Key_Data[data_offset + 2] = 0x00; - Key_Data[data_offset + 3] = 0x0F; - Key_Data[data_offset + 4] = 0xAC; - Key_Data[data_offset + 5] = 0x01; - - /* GTK KDE format - 802.11i-2004 Figure-43x */ - Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03); - Key_Data[data_offset + 7] = 0x00; /* Reserved Byte */ - - data_offset += 8; - } - - /* Encapsulate GTK */ - /* Only for pairwise_msg3_WPA2 and group_msg1 */ - if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) - || (MsgType == EAPOL_GROUP_MSG_1)) { - /* Fill in GTK */ - if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { - NdisMoveMemory(&Key_Data[data_offset], GTK, - LEN_AES_KEY); - data_offset += LEN_AES_KEY; - } else { - NdisMoveMemory(&Key_Data[data_offset], GTK, - TKIP_GTK_LENGTH); - data_offset += TKIP_GTK_LENGTH; - } - - GTK_Included = TRUE; - } - - /* This whole key-data field shall be encrypted if a GTK is included. */ - /* Encrypt the data material in key data field with KEK */ - if (GTK_Included) { - /*hex_dump("GTK_Included", Key_Data, data_offset); */ - - if ((keyDescVer == DESC_TYPE_AES)) { - u8 remainder = 0; - u8 pad_len = 0; - - /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */ - /* shall be used to encrypt the Key Data field using the KEK field from */ - /* the derived PTK. */ - - /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */ - /* shall be padded before encrypting if the key data length is less than 16 */ - /* octets or if it is not a multiple of 8. The padding consists of appending */ - /* a single octet 0xdd followed by zero or more 0x00 octets. */ - if ((remainder = data_offset & 0x07) != 0) { - int i; - - pad_len = (8 - remainder); - Key_Data[data_offset] = 0xDD; - for (i = 1; i < pad_len; i++) - Key_Data[data_offset + i] = 0; - - data_offset += pad_len; - } - - AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, - data_offset, Rc4GTK); - /* AES wrap function will grow 8 bytes in length */ - data_offset += 8; - } else { - /* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field - using the KEK field from the derived PTK. */ - - /* PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */ - /* put TxTsc in Key RSC field */ - pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; /*Init crc32. */ - - /* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */ - NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, - LEN_KEY_DESC_IV); - NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], - LEN_EAP_EK); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); /*INIT SBOX, KEYLEN+3(IV) */ - pAd->PrivateInfo.FCSCRC32 = - RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, - data_offset); - WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, - Key_Data, data_offset); - } - - NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset); - } else { - NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset); - } - - /* Update key data length field and total body length */ - SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset); - INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset); - - os_free_mem(NULL, mpool); - -} - -/* - ======================================================================== - - Routine Description: - Calcaulate MIC. It is used during 4-ways handsharking. - - Arguments: - pAd - pointer to our pAdapter context - PeerWepStatus - indicate the encryption type - - Return Value: - - Note: - - ======================================================================== -*/ -static void CalculateMIC(u8 KeyDescVer, - u8 * PTK, struct rt_eapol_packet * pMsg) -{ - u8 *OutBuffer; - unsigned long FrameLen = 0; - u8 mic[LEN_KEY_DESC_MIC]; - u8 digest[80]; - - /* allocate memory for MIC calculation */ - os_alloc_mem(NULL, (u8 **) & OutBuffer, 512); - - if (OutBuffer == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n")); - return; - } - /* make a frame for calculating MIC. */ - MakeOutgoingFrame(OutBuffer, &FrameLen, - CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg, - END_OF_ARGS); - - NdisZeroMemory(mic, sizeof(mic)); - - /* Calculate MIC */ - if (KeyDescVer == DESC_TYPE_AES) { - HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest, - SHA1_DIGEST_SIZE); - NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); - } else { - HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic, - MD5_DIGEST_SIZE); - } - - /* store the calculated MIC */ - NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); - - os_free_mem(NULL, OutBuffer); -} - -/* - ======================================================================== - - Routine Description: - Some received frames can't decrypt by Asic, so decrypt them by software. - - Arguments: - pAd - pointer to our pAdapter context - PeerWepStatus - indicate the encryption type - - Return Value: - NDIS_STATUS_SUCCESS - decryption successful - NDIS_STATUS_FAILURE - decryption failure - - ======================================================================== -*/ -int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd, - struct rt_rx_blk *pRxBlk, - IN NDIS_802_11_ENCRYPTION_STATUS - GroupCipher, struct rt_cipher_key *pShard_key) -{ - struct rt_rxwi * pRxWI = pRxBlk->pRxWI; - - /* handle WEP decryption */ - if (GroupCipher == Ndis802_11Encryption1Enabled) { - if (RTMPSoftDecryptWEP - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, - pShard_key)) { - - /*Minus IV[4] & ICV[4] */ - pRxWI->MPDUtotalByteCount -= 8; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : Software decrypt WEP data fails.\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } - /* handle TKIP decryption */ - else if (GroupCipher == Ndis802_11Encryption2Enabled) { - if (RTMPSoftDecryptTKIP - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, - pShard_key)) { - - /*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */ - pRxWI->MPDUtotalByteCount -= 20; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : RTMPSoftDecryptTKIP Failed\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } - /* handle AES decryption */ - else if (GroupCipher == Ndis802_11Encryption3Enabled) { - if (RTMPSoftDecryptAES - (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, - pShard_key)) { - - /*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */ - pRxWI->MPDUtotalByteCount -= 16; - } else { - DBGPRINT(RT_DEBUG_ERROR, - ("ERROR : RTMPSoftDecryptAES Failed\n")); - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - } else { - /* give up this frame */ - return NDIS_STATUS_FAILURE; - } - - return NDIS_STATUS_SUCCESS; - -} - -u8 *GetSuiteFromRSNIE(u8 *rsnie, - u32 rsnie_len, u8 type, u8 * count) -{ - struct rt_eid * pEid; - int len; - u8 *pBuf; - int offset = 0; - struct rt_rsnie_auth *pAkm; - u16 acount; - BOOLEAN isWPA2 = FALSE; - - pEid = (struct rt_eid *) rsnie; - len = rsnie_len - 2; /* exclude IE and length */ - pBuf = (u8 *)& pEid->Octet[0]; - - /* set default value */ - *count = 0; - - /* Check length */ - if ((len <= 0) || (pEid->Len != len)) { - DBGPRINT_ERR("%s : The length is invalid\n", __func__); - return NULL; - } - /* Check WPA or WPA2 */ - if (pEid->Eid == IE_WPA) { - struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf; - u16 ucount; - - if (len < sizeof(struct rt_rsnie)) { - DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__); - return NULL; - } - /* Get the count of pairwise cipher */ - ucount = cpu2le16(pRsnie->ucount); - if (ucount > 2) { - DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); - return NULL; - } - /* Get the group cipher */ - if (type == GROUP_SUITE) { - *count = 1; - return pRsnie->mcast; - } - /* Get the pairwise cipher suite */ - else if (type == PAIRWISE_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s : The count of pairwise cipher is %d\n", - __func__, ucount)); - *count = ucount; - return pRsnie->ucast[0].oui; - } - - offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1)); - - } else if (pEid->Eid == IE_RSN) { - struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf; - u16 ucount; - - isWPA2 = TRUE; - - if (len < sizeof(struct rt_rsnie2)) { - DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__); - return NULL; - } - /* Get the count of pairwise cipher */ - ucount = cpu2le16(pRsnie->ucount); - if (ucount > 2) { - DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); - return NULL; - } - /* Get the group cipher */ - if (type == GROUP_SUITE) { - *count = 1; - return pRsnie->mcast; - } - /* Get the pairwise cipher suite */ - else if (type == PAIRWISE_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, - ("%s : The count of pairwise cipher is %d\n", - __func__, ucount)); - *count = ucount; - return pRsnie->ucast[0].oui; - } - - offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1)); - - } else { - DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid); - return NULL; - } - - /* skip group cipher and pairwise cipher suite */ - pBuf += offset; - len -= offset; - - if (len < sizeof(struct rt_rsnie_auth)) { - DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__); - return NULL; - } - /* pointer to AKM count */ - pAkm = (struct rt_rsnie_auth *)pBuf; - - /* Get the count of pairwise cipher */ - acount = cpu2le16(pAkm->acount); - if (acount > 2) { - DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount); - return NULL; - } - /* Get the AKM suite */ - if (type == AKM_SUITE) { - DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n", - __func__, acount)); - *count = acount; - return pAkm->auth[0].oui; - } - offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1)); - - pBuf += offset; - len -= offset; - - /* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */ - if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) { - /* Skip RSN capability and PMKID-Count */ - pBuf += (sizeof(RSN_CAPABILITIES) + 2); - len -= (sizeof(RSN_CAPABILITIES) + 2); - - /* Get PMKID */ - if (type == PMKID_LIST) { - *count = 1; - return pBuf; - } - } else { - DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__); - return NULL; - } - - *count = 0; - /*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */ - return NULL; - -} - -void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len) -{ - u8 *pSuite = NULL; - u8 count; - - hex_dump("RSNIE", rsnie, rsnie_len); - - /* group cipher */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count); - if (pSuite != NULL) { - hex_dump("group cipher", pSuite, 4 * count); - } - /* pairwise cipher */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count); - if (pSuite != NULL) { - hex_dump("pairwise cipher", pSuite, 4 * count); - } - /* AKM */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count); - if (pSuite != NULL) { - hex_dump("AKM suite", pSuite, 4 * count); - } - /* PMKID */ - pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count); - if (pSuite != NULL) { - hex_dump("PMKID", pSuite, LEN_PMKID); - } - -} - -void RTMPInsertRSNIE(u8 *pFrameBuf, - unsigned long *pFrameLen, - u8 *rsnie_ptr, - u8 rsnie_len, - u8 *pmkid_ptr, u8 pmkid_len) -{ - u8 *pTmpBuf; - unsigned long TempLen = 0; - u8 extra_len = 0; - u16 pmk_count = 0; - u8 ie_num; - u8 total_len = 0; - u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; - - pTmpBuf = pFrameBuf; - - /* PMKID-List Must larger than 0 and the multiple of 16. */ - if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) { - extra_len = sizeof(u16)+ pmkid_len; - - pmk_count = (pmkid_len >> 4); - pmk_count = cpu2le16(pmk_count); - } else { - DBGPRINT(RT_DEBUG_WARN, - ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n", - __func__, pmkid_len)); - } - - if (rsnie_len != 0) { - ie_num = IE_WPA; - total_len = rsnie_len; - - if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) { - ie_num = IE_RSN; - total_len += extra_len; - } - - /* construct RSNIE body */ - MakeOutgoingFrame(pTmpBuf, &TempLen, - 1, &ie_num, - 1, &total_len, - rsnie_len, rsnie_ptr, END_OF_ARGS); - - pTmpBuf += TempLen; - *pFrameLen = *pFrameLen + TempLen; - - if (ie_num == IE_RSN) { - /* Insert PMKID-List field */ - if (extra_len > 0) { - MakeOutgoingFrame(pTmpBuf, &TempLen, - 2, &pmk_count, - pmkid_len, pmkid_ptr, - END_OF_ARGS); - - pTmpBuf += TempLen; - *pFrameLen = *pFrameLen + TempLen; - } - } - } - - return; -} |