aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/rt3070/sta/wpa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rt3070/sta/wpa.c')
-rw-r--r--drivers/staging/rt3070/sta/wpa.c2100
1 files changed, 1 insertions, 2099 deletions
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
index 63d08306bf6..95543bb1f0e 100644
--- a/drivers/staging/rt3070/sta/wpa.c
+++ b/drivers/staging/rt3070/sta/wpa.c
@@ -1,2099 +1 @@
-/*
- *************************************************************************
- * 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"
-
-#define WPARSNIE 0xdd
-#define WPA2RSNIE 0x30
-
-//extern UCHAR BIT8[];
-UCHAR CipherWpaPskTkip[] = {
- 0xDD, 0x16, // RSN IE
- 0x00, 0x50, 0xf2, 0x01, // oui
- 0x01, 0x00, // Version
- 0x00, 0x50, 0xf2, 0x02, // Multicast
- 0x01, 0x00, // Number of unicast
- 0x00, 0x50, 0xf2, 0x02, // unicast
- 0x01, 0x00, // number of authentication method
- 0x00, 0x50, 0xf2, 0x02 // authentication
- };
-UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
-
-UCHAR CipherWpaPskAes[] = {
- 0xDD, 0x16, // RSN IE
- 0x00, 0x50, 0xf2, 0x01, // oui
- 0x01, 0x00, // Version
- 0x00, 0x50, 0xf2, 0x04, // Multicast
- 0x01, 0x00, // Number of unicast
- 0x00, 0x50, 0xf2, 0x04, // unicast
- 0x01, 0x00, // number of authentication method
- 0x00, 0x50, 0xf2, 0x02 // authentication
- };
-UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
-
-UCHAR CipherSuiteCiscoCCKM[] = {
- 0xDD, 0x16, // RSN IE
- 0x00, 0x50, 0xf2, 0x01, // oui
- 0x01, 0x00, // Version
- 0x00, 0x40, 0x96, 0x01, // Multicast
- 0x01, 0x00, // Number of uicast
- 0x00, 0x40, 0x96, 0x01, // unicast
- 0x01, 0x00, // number of authentication method
- 0x00, 0x40, 0x96, 0x00 // Authentication
- };
-UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
-
-UCHAR CipherSuiteCiscoCCKM24[] = {
- 0xDD, 0x18, // RSN IE
- 0x00, 0x50, 0xf2, 0x01, // oui
- 0x01, 0x00, // Version
- 0x00, 0x40, 0x96, 0x01, // Multicast
- 0x01, 0x00, // Number of uicast
- 0x00, 0x40, 0x96, 0x01, // unicast
- 0x01, 0x00, // number of authentication method
- 0x00, 0x40, 0x96, 0x00,
- 0x28, 0x00// Authentication
- };
-
-UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
-
-UCHAR CipherSuiteCCXTkip[] = {
- 0xDD, 0x16, // RSN IE
- 0x00, 0x50, 0xf2, 0x01, // oui
- 0x01, 0x00, // Version
- 0x00, 0x50, 0xf2, 0x02, // Multicast
- 0x01, 0x00, // Number of unicast
- 0x00, 0x50, 0xf2, 0x02, // unicast
- 0x01, 0x00, // number of authentication method
- 0x00, 0x50, 0xf2, 0x01 // authentication
- };
-UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
-
-UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
-UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
-
-UCHAR EAPOL_FRAME[] = {0x88, 0x8E};
-
-BOOLEAN CheckRSNIE(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pData,
- IN UCHAR DataLen,
- OUT UCHAR *Offset);
-
-void inc_byte_array(UCHAR *counter, int len);
-
-/*
- ========================================================================
-
- 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 avaliable
-
- ========================================================================
-*/
-BOOLEAN WpaMsgTypeSubst(
- IN UCHAR EAPType,
- OUT 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;
-}
-
-/*
- ==========================================================================
- Description:
- association state machine init, including state transition and timer init
- Parameters:
- S - pointer to the association state machine
- ==========================================================================
- */
-VOID WpaPskStateMachineInit(
- IN PRTMP_ADAPTER pAd,
- IN STATE_MACHINE *S,
- OUT STATE_MACHINE_FUNC Trans[])
-{
- StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
- StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
-}
-
-/*
- ==========================================================================
- 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(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- INT MsgType = EAPOL_MSG_INVALID;
- PKEY_DESCRIPTER pKeyDesc;
- PHEADER_802_11 pHeader; //red
- UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
- UCHAR EapolVr;
- KEY_INFO peerKeyInfo;
-
- DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
-
- // Get 802.11 header first
- pHeader = (PHEADER_802_11) Elem->Msg;
-
- // Get EAPoL-Key Descriptor
- pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
-
- NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
- NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
-
- *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
-
-
- // 1. Check EAPOL frame version and type
- EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
-
- if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
- return;
- }
-
- // First validate replay counter, only accept message with larger replay counter
- // Let equal pass, some AP start with all zero replay counter
- NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
-
- if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
- (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
- {
- DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n"));
- return;
- }
-
- // Process WPA2PSK frame
- if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
- {
- if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
- (peerKeyInfo.EKD_DL == 0) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 0) &&
- (peerKeyInfo.Secure == 0) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_PAIR_MSG_1;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
- } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
- (peerKeyInfo.EKD_DL == 1) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 1) &&
- (peerKeyInfo.Secure == 1) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_PAIR_MSG_3;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
- } else if((peerKeyInfo.KeyType == GROUPKEY) &&
- (peerKeyInfo.EKD_DL == 1) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 1) &&
- (peerKeyInfo.Secure == 1) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_GROUP_MSG_1;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
- }
-
- // We will assume link is up (assoc suceess and port not secured).
- // All state has to be able to process message from previous state
- switch(pAd->StaCfg.WpaState)
- {
- case SS_START:
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- Wpa2PairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- }
- break;
-
- case SS_WAIT_MSG_3:
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- Wpa2PairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- }
- else if(MsgType == EAPOL_PAIR_MSG_3)
- {
- Wpa2PairMsg3Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_GROUP;
- }
- break;
-
- case SS_WAIT_GROUP: // When doing group key exchange
- case SS_FINISH: // This happened when update group key
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- // Reset port secured variable
- pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
- Wpa2PairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- }
- else if(MsgType == EAPOL_PAIR_MSG_3)
- {
- // Reset port secured variable
- pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
- Wpa2PairMsg3Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_GROUP;
- }
- else if(MsgType == EAPOL_GROUP_MSG_1)
- {
- WpaGroupMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_FINISH;
- }
- break;
-
- default:
- break;
- }
- }
- // Process WPAPSK Frame
- // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
- else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
- {
- if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
- (peerKeyInfo.KeyIndex == 0) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 0) &&
- (peerKeyInfo.Secure == 0) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_PAIR_MSG_1;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
- }
- else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
- (peerKeyInfo.KeyIndex == 0) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 1) &&
- (peerKeyInfo.Secure == 0) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_PAIR_MSG_3;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
- }
- else if((peerKeyInfo.KeyType == GROUPKEY) &&
- (peerKeyInfo.KeyIndex != 0) &&
- (peerKeyInfo.KeyAck == 1) &&
- (peerKeyInfo.KeyMic == 1) &&
- (peerKeyInfo.Secure == 1) &&
- (peerKeyInfo.Error == 0) &&
- (peerKeyInfo.Request == 0))
- {
- MsgType = EAPOL_GROUP_MSG_1;
- DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
- }
-
- // We will assume link is up (assoc suceess and port not secured).
- // All state has to be able to process message from previous state
- switch(pAd->StaCfg.WpaState)
- {
- case SS_START:
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- WpaPairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- }
- break;
-
- case SS_WAIT_MSG_3:
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- WpaPairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- }
- else if(MsgType == EAPOL_PAIR_MSG_3)
- {
- WpaPairMsg3Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_GROUP;
- }
- break;
-
- case SS_WAIT_GROUP: // When doing group key exchange
- case SS_FINISH: // This happened when update group key
- if(MsgType == EAPOL_PAIR_MSG_1)
- {
- WpaPairMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
- // Reset port secured variable
- pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
- }
- else if(MsgType == EAPOL_PAIR_MSG_3)
- {
- WpaPairMsg3Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_WAIT_GROUP;
- // Reset port secured variable
- pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
- }
- else if(MsgType == EAPOL_GROUP_MSG_1)
- {
- WpaGroupMsg1Action(pAd, Elem);
- pAd->StaCfg.WpaState = SS_FINISH;
- }
- break;
-
- default:
- break;
- }
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Process Pairwise key 4-way handshaking
-
- Arguments:
- pAd Pointer to our adapter
- Elem Message body
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID WpaPairMsg1Action(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- PHEADER_802_11 pHeader;
- UCHAR *mpool, *PTK, *digest;
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- PEAPOL_PACKET pMsg1;
- EAPOL_PACKET Packet;
- UCHAR Mic[16];
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
-
- // allocate memory pool
- os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
-
- if (mpool == NULL)
- return;
-
- // PTK Len = 80.
- PTK = (UCHAR *) ROUND_UP(mpool, 4);
- // digest Len = 80.
- digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
-
- pHeader = (PHEADER_802_11) Elem->Msg;
-
- // Process message 1 from authenticator
- pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
- // 1. Save Replay counter, it will use to verify message 3 and construct message 2
- NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // 2. Save ANonce
- NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
- // Generate random SNonce
- GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
-
- // Calc PTK(ANonce, SNonce)
- WpaCountPTK(pAd,
- pAd->StaCfg.PMK,
- pAd->StaCfg.ANonce,
- pAd->CommonCfg.Bssid,
- pAd->StaCfg.SNonce,
- pAd->CurrentAddress,
- PTK,
- LEN_PTK);
-
- // Save key to PTK entry
- NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
-
- // init 802.3 header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- // Zero Message 2 body
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
- //
- // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
- //
- Packet.KeyDesc.Type = WPA1_KEY_DESC;
- // 1. Key descriptor version and appropriate RSN IE
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
- }
- else // TKIP
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
- }
-
- // fill in Data Material and its length
- Packet.KeyDesc.KeyData[0] = IE_WPA;
- Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
- Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
- NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
-
- // Update packet length after decide Key data payload
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
-
- // Update Key length
- Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
- Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
- // 2. Key Type PeerKey
- Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
- // 3. KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
- //Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-
- // 4. Fill SNonce
- NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
-
- // 5. Key Replay Count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
- // Out buffer for transmitting message 2
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- {
- os_free_mem(pAd, mpool);
- return;
- }
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // 6. Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- { // AES
-
- HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- { // TKIP
- hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
- //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
-
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
-
- // 5. Copy frame to Tx ring and send Msg 2 to authenticator
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
- MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
- os_free_mem(pAd, (PUCHAR)mpool);
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
-}
-
-VOID Wpa2PairMsg1Action(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- PHEADER_802_11 pHeader;
- UCHAR *mpool, *PTK, *digest;
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- PEAPOL_PACKET pMsg1;
- EAPOL_PACKET Packet;
- UCHAR Mic[16];
-
- DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
-
- // allocate memory pool
- os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
-
- if (mpool == NULL)
- return;
-
- // PTK Len = 80.
- PTK = (UCHAR *) ROUND_UP(mpool, 4);
- // digest Len = 80.
- digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
-
- pHeader = (PHEADER_802_11) Elem->Msg;
-
- // Process message 1 from authenticator
- pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
- // 1. Save Replay counter, it will use to verify message 3 and construct message 2
- NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // 2. Save ANonce
- NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
-
- // Generate random SNonce
- GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
-
- if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
- {
- // cached PMKID
- }
-
- // Calc PTK(ANonce, SNonce)
- WpaCountPTK(pAd,
- pAd->StaCfg.PMK,
- pAd->StaCfg.ANonce,
- pAd->CommonCfg.Bssid,
- pAd->StaCfg.SNonce,
- pAd->CurrentAddress,
- PTK,
- LEN_PTK);
-
- // Save key to PTK entry
- NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
-
- // init 802.3 header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- // Zero message 2 body
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
- //
- // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
- //
- Packet.KeyDesc.Type = WPA2_KEY_DESC;
-
- // 1. Key descriptor version and appropriate RSN IE
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
- }
- else // TKIP
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
- }
-
- // fill in Data Material and its length
- Packet.KeyDesc.KeyData[0] = IE_WPA2;
- Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
- Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
- NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
-
- // Update packet length after decide Key data payload
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
-
- // 2. Key Type PeerKey
- Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
- // 3. KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
- // Update Key Length
- Packet.KeyDesc.KeyLength[0] = 0;
- Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
-
- // 4. Fill SNonce
- NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
-
- // 5. Key Replay Count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
- // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
- // Out buffer for transmitting message 2
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- {
- os_free_mem(pAd, mpool);
- return;
- }
-
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // 6. Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- {
- hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-
- // Make Transmitting frame
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
-
- // 5. Copy frame to Tx ring
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
- MlmeFreeMemory(pAd, pOutBuffer);
- os_free_mem(pAd, mpool);
-
- DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
-
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Process Pairwise key 4-way handshaking
-
- Arguments:
- pAd Pointer to our adapter
- Elem Message body
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID WpaPairMsg3Action(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- PHEADER_802_11 pHeader;
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- EAPOL_PACKET Packet;
- PEAPOL_PACKET pMsg3;
- UCHAR Mic[16], OldMic[16];
- MAC_TABLE_ENTRY *pEntry = NULL;
- UCHAR skip_offset;
- KEY_INFO peerKeyInfo;
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
-
- // Record 802.11 header & the received EAPOL packet Msg3
- pHeader = (PHEADER_802_11) Elem->Msg;
- pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
- NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
- NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
- *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
-
- // 1. Verify cipher type match
- if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
- {
- return;
- }
- else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
- {
- return;
- }
-
- // Verify RSN IE
- //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
- if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
- {
- DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
- hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
- hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
- return;
- }
- else
- DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
-
-
- // 2. Check MIC value
- // Save the MIC and replace with zero
- NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
- NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- UCHAR digest[80];
-
- HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else // TKIP
- {
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
- }
-
- if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
- {
- DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
- return;
- }
- else
- DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-
- // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
- if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
- return;
-
- // Update new replay counter
- NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // 4. Double check ANonce
- if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
- return;
-
- // init 802.3 header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- // Zero Message 4 body
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
-
- //
- // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
- //
- Packet.KeyDesc.Type = WPA1_KEY_DESC;
-
- // Key descriptor version and appropriate RSN IE
- Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
- // Update Key Length
- Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
- Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
-
- // Key Type PeerKey
- Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
- // KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
- // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
- // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3
- Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
-
- // Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
- // Key Replay count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // Out buffer for transmitting message 4
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- return;
-
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- UCHAR digest[80];
-
- HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- {
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
- // Update PTK
- // Prepare pair-wise key information into shared key table
- NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
- pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
- NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
- NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
- NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
- // Decide its ChiperAlg
- if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
- else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
- else
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
- // Update these related information to 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 = pAd->SharedKey[BSS0][0].CipherAlg;
-
- // Update pairwise key information to ASIC Shared Key Table
- AsicAddSharedKeyEntry(pAd,
- BSS0,
- 0,
- pAd->SharedKey[BSS0][0].CipherAlg,
- pAd->SharedKey[BSS0][0].Key,
- pAd->SharedKey[BSS0][0].TxMic,
- pAd->SharedKey[BSS0][0].RxMic);
-
- // Update ASIC WCID attribute table and IVEIV table
- RTMPAddWcidAttributeEntry(pAd,
- BSS0,
- 0,
- pAd->SharedKey[BSS0][0].CipherAlg,
- pEntry);
-
- // Make transmitting frame
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
-
- // Copy frame to Tx ring and Send Message 4 to authenticator
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
- MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
-}
-
-VOID Wpa2PairMsg3Action(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- PHEADER_802_11 pHeader;
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- EAPOL_PACKET Packet;
- PEAPOL_PACKET pMsg3;
- UCHAR Mic[16], OldMic[16];
- UCHAR *mpool, *KEYDATA, *digest;
- UCHAR Key[32];
- MAC_TABLE_ENTRY *pEntry = NULL;
- KEY_INFO peerKeyInfo;
-
- // allocate memory
- os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
-
- if(mpool == NULL)
- return;
-
- // KEYDATA Len = 512.
- KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
- // digest Len = 80.
- digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
-
- DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
-
- pHeader = (PHEADER_802_11) Elem->Msg;
-
- // Process message 3 frame.
- pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
- NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
- NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
- *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
- // 1. Verify cipher type match
- if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
- else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // 2. Check MIC value
- // Save the MIC and replace with zero
- NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
- NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
- if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- {
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
- }
-
- if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
- {
- DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
- else
- DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
-
- // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
- if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Update new replay counter
- NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // 4. Double check ANonce
- if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Obtain GTK
- // 5. Decrypt GTK from Key Data
- DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // Decrypt AES GTK
- AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
- }
- else // TKIP
- {
- INT i;
- // Decrypt TKIP GTK
- // Construct 32 bytes RC4 Key
- NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
- NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
- ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
- //discard first 256 bytes
- for(i = 0; i < 256; i++)
- ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
- // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
- ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
- }
-
- if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Update GTK to ASIC
- // Update group key information to ASIC Shared Key Table
- AsicAddSharedKeyEntry(pAd,
- BSS0,
- pAd->StaCfg.DefaultKeyId,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
-
- // Update ASIC WCID attribute table and IVEIV table
- RTMPAddWcidAttributeEntry(pAd,
- BSS0,
- pAd->StaCfg.DefaultKeyId,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
- NULL);
-
- // init 802.3 header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- // Zero message 4 body
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
-
- //
- // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
- //
- Packet.KeyDesc.Type = WPA2_KEY_DESC;
-
- // Key descriptor version and appropriate RSN IE
- Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
- // Update Key Length
- Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
- Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
-
- // Key Type PeerKey
- Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
- // KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
- Packet.KeyDesc.KeyInfo.Secure = 1;
-
- // Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
- // Key Replay count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // Out buffer for transmitting message 4
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- {
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
- // Update PTK
- // Prepare pair-wise key information into shared key table
- NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
- pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
- NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
- NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
- NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
- // Decide its ChiperAlg
- if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
- else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
- else
- pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
- // Update these related information to 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 = pAd->SharedKey[BSS0][0].CipherAlg;
-
- // Update pairwise key information to ASIC Shared Key Table
- AsicAddSharedKeyEntry(pAd,
- BSS0,
- 0,
- pAd->SharedKey[BSS0][0].CipherAlg,
- pAd->SharedKey[BSS0][0].Key,
- pAd->SharedKey[BSS0][0].TxMic,
- pAd->SharedKey[BSS0][0].RxMic);
-
- // Update ASIC WCID attribute table and IVEIV table
- RTMPAddWcidAttributeEntry(pAd,
- BSS0,
- 0,
- pAd->SharedKey[BSS0][0].CipherAlg,
- pEntry);
-
- // Make Transmitting frame
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
-
- // Copy frame to Tx ring and Send Message 4 to authenticator
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
-
- // set 802.1x port control
- //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
- STA_PORT_SECURED(pAd);
-
- // Indicate Connected for GUI
- pAd->IndicateMediaState = NdisMediaStateConnected;
-
- MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
- os_free_mem(pAd, (PUCHAR)mpool);
-
-
- // send wireless event - for set key done WPA2
- if (pAd->CommonCfg.bWirelessEvent)
- RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
-
- DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
-
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Process Group key 2-way handshaking
-
- Arguments:
- pAd Pointer to our adapter
- Elem Message body
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID WpaGroupMsg1Action(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- EAPOL_PACKET Packet;
- PEAPOL_PACKET pGroup;
- UCHAR *mpool, *digest, *KEYDATA;
- UCHAR Mic[16], OldMic[16];
- UCHAR GTK[32], Key[32];
- KEY_INFO peerKeyInfo;
-
- // allocate memory
- os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
-
- if(mpool == NULL)
- return;
-
- // digest Len = 80.
- digest = (UCHAR *) ROUND_UP(mpool, 4);
- // KEYDATA Len = 512.
- KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
-
- // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
- pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
- NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
- NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
-
- *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
-
- // 0. Check cipher type match
- if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
- else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // 1. Verify Replay counter
- // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
- if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Update new replay counter
- NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // 2. Verify MIC is valid
- // Save the MIC and replace with zero
- NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
- NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- { // AES
- HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- { // TKIP
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
- }
-
- if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
- {
- DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
- MlmeFreeMemory(pAd, (PUCHAR)mpool);
- return;
- }
- else
- DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
-
-
- // 3. Decrypt GTK from Key Data
- if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // Decrypt AES GTK
- AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
- }
- else // TKIP
- {
- INT i;
-
- // Decrypt TKIP GTK
- // Construct 32 bytes RC4 Key
- NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
- NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
- ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
- //discard first 256 bytes
- for(i = 0; i < 256; i++)
- ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
- // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
- ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
- }
-
- // Process decrypted key data material
- // Parse keyData to handle KDE format for WPA2PSK
- if (peerKeyInfo.EKD_DL)
- {
- if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
- {
- os_free_mem(pAd, (PUCHAR)mpool);
- return;
- }
- }
- else // WPAPSK
- {
- // set key material, TxMic and RxMic for WPAPSK
- NdisMoveMemory(GTK, KEYDATA, 32);
- NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
- pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
-
- // Prepare pair-wise key information into shared key table
- NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
-
- // Update Shared Key CipherAlg
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
- if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
- else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
-
- //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
- }
-
- // Update group key information to ASIC Shared Key Table
- AsicAddSharedKeyEntry(pAd,
- BSS0,
- pAd->StaCfg.DefaultKeyId,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
-
- // Update ASIC WCID attribute table and IVEIV table
- RTMPAddWcidAttributeEntry(pAd,
- BSS0,
- pAd->StaCfg.DefaultKeyId,
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
- NULL);
-
- // set 802.1x port control
- //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
- STA_PORT_SECURED(pAd);
-
- // Indicate Connected for GUI
- pAd->IndicateMediaState = NdisMediaStateConnected;
-
- // init header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- // Zero Group message 1 body
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
-
- //
- // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
- //
- if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
- {
- Packet.KeyDesc.Type = WPA2_KEY_DESC;
- }
- else
- {
- Packet.KeyDesc.Type = WPA1_KEY_DESC;
- }
-
- // Key descriptor version and appropriate RSN IE
- Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
-
- // Update Key Length
- Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
- Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
-
- // Key Index as G-Msg 1
- if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
- Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
-
- // Key Type Group key
- Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
-
- // KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
- // Secure bit
- Packet.KeyDesc.KeyInfo.Secure = 1;
-
- // Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
- // Key Replay count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
-
- // Out buffer for transmitting group message 2
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- {
- MlmeFreeMemory(pAd, (PUCHAR)mpool);
- return;
- }
-
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- // AES
- HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- {
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
-
- // 5. Copy frame to Tx ring and prepare for encryption
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
-
- // 6 Free allocated memory
- MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
- os_free_mem(pAd, (PUCHAR)mpool);
-
- // send wireless event - for set key done WPA2
- if (pAd->CommonCfg.bWirelessEvent)
- RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Init WPA MAC header
-
- Arguments:
- pAd Pointer to our adapter
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID WpaMacHeaderInit(
- IN PRTMP_ADAPTER pAd,
- IN OUT PHEADER_802_11 pHdr80211,
- IN UCHAR wep,
- IN PUCHAR pAddr1)
-{
- NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
- pHdr80211->FC.Type = BTYPE_DATA;
- pHdr80211->FC.ToDs = 1;
- if (wep == 1)
- pHdr80211->FC.Wep = 1;
-
- // Addr1: BSSID, Addr2: SA, Addr3: DA
- COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
- COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
- COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
- pHdr80211->Sequence = pAd->Sequence;
-}
-
-/*
- ========================================================================
-
- 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
- PNDIS_PACKET Pointer to outgoing Ndis frame
- NumberOfFrag Number of fragment required
-
- Return Value:
- None
-
- Note:
-
- ========================================================================
-*/
-VOID RTMPToWirelessSta(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pHeader802_3,
- IN UINT HdrLen,
- IN PUCHAR pData,
- IN UINT DataLen,
- IN BOOLEAN is4wayFrame)
-
-{
- NDIS_STATUS Status;
- PNDIS_PACKET pPacket;
- UCHAR Index;
-
- do
- {
- // 1. build a NDIS packet and call RTMPSendPacket();
- // be careful about how/when to release this internal allocated NDIS PACKET buffer
- Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
- if (Status != NDIS_STATUS_SUCCESS)
- break;
-
- if (is4wayFrame)
- RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
- else
- RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
-
- // 2. send out the packet
- Status = STASendPacket(pAd, pPacket);
- if(Status == NDIS_STATUS_SUCCESS)
- {
- // 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);
-
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Check Sanity RSN IE form AP
-
- Arguments:
-
- Return Value:
-
-
- ========================================================================
-*/
-BOOLEAN CheckRSNIE(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pData,
- IN UCHAR DataLen,
- OUT UCHAR *Offset)
-{
- PUCHAR pVIE;
- UCHAR len;
- PEID_STRUCT pEid;
- BOOLEAN result = FALSE;
-
- pVIE = pData;
- len = DataLen;
- *Offset = 0;
-
- while (len > sizeof(RSNIE2))
- {
- pEid = (PEID_STRUCT) pVIE;
- // WPA RSN IE
- if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
- {
- if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
- (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
- (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
- {
- DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (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 ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
- (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
- (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
- {
- DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
- result = TRUE;
- }
-
- *Offset += (pEid->Len + 2);
- }
- else
- {
- break;
- }
-
- pVIE += (pEid->Len + 2);
- len -= (pEid->Len + 2);
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
-
- 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 ParseKeyData(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pKeyData,
- IN UCHAR KeyDataLen,
- IN UCHAR bPairewise)
-{
- PKDE_ENCAP pKDE = NULL;
- PUCHAR pMyKeyData = pKeyData;
- UCHAR KeyDataLength = KeyDataLen;
- UCHAR GTKLEN;
- UCHAR skip_offset;
-
- // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
- if (bPairewise)
- {
- // Check RSN IE whether it is WPA2/WPA2PSK
- if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
- {
- DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
- hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
- return FALSE;
- }
- else
- {
- // skip RSN IE
- pMyKeyData += skip_offset;
- KeyDataLength -= skip_offset;
-
- //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
- }
- }
-
- DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
-
- // Parse EKD format
- if (KeyDataLength >= 8)
- {
- pKDE = (PKDE_ENCAP) pMyKeyData;
- }
- else
- {
- DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
- return FALSE;
- }
-
-
- // Sanity check - shared key index should not be 0
- if (pKDE->GTKEncap.Kid == 0)
- {
- DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
- return FALSE;
- }
-
- // 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_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
-
- // Update GTK
- // set key material, TxMic and RxMic for WPAPSK
- NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
- pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
-
- // Update shared key table
- NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
- NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
-
- // Update Shared Key CipherAlg
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
- if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
- else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
- pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
-
- return TRUE;
-
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Cisco CCKM PRF function
-
- Arguments:
- key Cisco Base Transient Key (BTK)
- key_len The key length of the BTK
- data Ruquest Number(RN) + BSSID
- data_len The length of the data
- output Store for PTK(Pairwise transient keys)
- len The length of the output
- Return Value:
- None
-
- Note:
- 802.1i Annex F.9
-
- ========================================================================
-*/
-VOID CCKMPRF(
- IN UCHAR *key,
- IN INT key_len,
- IN UCHAR *data,
- IN INT data_len,
- OUT UCHAR *output,
- IN INT len)
-{
- INT i;
- UCHAR input[1024];
- INT currentindex = 0;
- INT total_len;
-
- NdisMoveMemory(input, data, data_len);
- total_len = data_len;
- input[total_len] = 0;
- total_len++;
- for (i = 0; i < (len + 19) / 20; i++)
- {
- HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
- currentindex += 20;
- input[total_len - 1]++;
- }
-}
-
-/*
- ========================================================================
-
- Routine Description:
- Process MIC error indication and record MIC error timer.
-
- Arguments:
- pAd Pointer to our adapter
- pWpaKey Pointer to the WPA key structure
-
- Return Value:
- None
-
- IRQL = DISPATCH_LEVEL
-
- Note:
-
- ========================================================================
-*/
-VOID RTMPReportMicError(
- IN PRTMP_ADAPTER pAd,
- IN PCIPHER_KEY pWpaKey)
-{
- ULONG Now;
- UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
-
- // Record Last MIC error time and count
- Now = jiffies;
- if (pAd->StaCfg.MicErrCnt == 0)
- {
- pAd->StaCfg.MicErrCnt++;
- pAd->StaCfg.LastMicErrorTime = Now;
- NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
- }
- else if (pAd->StaCfg.MicErrCnt == 1)
- {
- if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
- {
- // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
- pAd->StaCfg.LastMicErrorTime = Now;
- }
- else
- {
-
- if (pAd->CommonCfg.bWirelessEvent)
- RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-
- pAd->StaCfg.LastMicErrorTime = Now;
- // Violate MIC error counts, MIC countermeasures kicks in
- pAd->StaCfg.MicErrCnt++;
- // We shall block all reception
- // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
- //
- // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
- // if pAd->StaCfg.MicErrCnt greater than 2.
- //
- // RTMPRingCleanUp(pAd, QID_AC_BK);
- // RTMPRingCleanUp(pAd, QID_AC_BE);
- // RTMPRingCleanUp(pAd, QID_AC_VI);
- // RTMPRingCleanUp(pAd, QID_AC_VO);
- // RTMPRingCleanUp(pAd, QID_HCCA);
- }
- }
- else
- {
- // MIC error count >= 2
- // This should not happen
- ;
- }
- MlmeEnqueue(pAd,
- MLME_CNTL_STATE_MACHINE,
- OID_802_11_MIC_FAILURE_REPORT_FRAME,
- 1,
- &unicastKey);
-
- if (pAd->StaCfg.MicErrCnt == 2)
- {
- RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
- }
-}
-
-
-#ifdef WPA_SUPPLICANT_SUPPORT
-#define LENGTH_EAP_H 4
-// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
-INT WpaCheckEapCode(
- IN PRTMP_ADAPTER pAd,
- IN PUCHAR pFrame,
- IN USHORT FrameLen,
- IN USHORT OffSet)
-{
-
- PUCHAR pData;
- INT result = 0;
-
- if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
- return result;
-
- pData = pFrame + OffSet; // skip offset bytes
-
- if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
- {
- result = *(pData+4); // EAP header - Code
- }
-
- return result;
-}
-
-VOID WpaSendMicFailureToWpaSupplicant(
- IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bUnicast)
-{
- union iwreq_data wrqu;
- char custom[IW_CUSTOM_MAX] = {0};
-
- sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
- if (bUnicast)
- sprintf(custom, "%s unicast", custom);
- wrqu.data.length = strlen(custom);
- wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
-
- return;
-}
-#endif // WPA_SUPPLICANT_SUPPORT //
-
-VOID WpaMicFailureReportFrame(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-{
- PUCHAR pOutBuffer = NULL;
- UCHAR Header802_3[14];
- ULONG FrameLen = 0;
- EAPOL_PACKET Packet;
- UCHAR Mic[16];
- BOOLEAN bUnicast;
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
-
- bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
- pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
-
- // init 802.3 header and Fill Packet
- MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
-
- NdisZeroMemory(&Packet, sizeof(Packet));
- Packet.ProVer = EAPOL_VER;
- Packet.ProType = EAPOLKey;
-
- Packet.KeyDesc.Type = WPA1_KEY_DESC;
-
- // Request field presented
- Packet.KeyDesc.KeyInfo.Request = 1;
-
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
- }
- else // TKIP
- {
- Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
- }
-
- Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
-
- // KeyMic field presented
- Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
- // Error field presented
- Packet.KeyDesc.KeyInfo.Error = 1;
-
- // Update packet length after decide Key data payload
- Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
-
- // Key Replay Count
- NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
- inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
-
- // Convert to little-endian format.
- *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
-
-
- MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
- if(pOutBuffer == NULL)
- {
- return;
- }
-
- // Prepare EAPOL frame for MIC calculation
- // Be careful, only EAPOL frame is counted for MIC calculation
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // Prepare and Fill MIC value
- NdisZeroMemory(Mic, sizeof(Mic));
- if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
- { // AES
- UCHAR digest[20] = {0};
- HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
- NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
- }
- else
- { // TKIP
- hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
- }
- NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- LENGTH_802_3, &Header802_3,
- Packet.Body_Len[1] + 4, &Packet,
- END_OF_ARGS);
-
- // opy frame to Tx ring and send MIC failure report frame to authenticator
- RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
-
- MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
-
- DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
-}
-
-/** from wpa_supplicant
- * inc_byte_array - Increment arbitrary length byte array by one
- * @counter: Pointer to byte array
- * @len: Length of the counter in bytes
- *
- * This function increments the last byte of the counter by one and continues
- * rolling over to more significant bytes if the byte was incremented from
- * 0xff to 0x00.
- */
-void inc_byte_array(UCHAR *counter, int len)
-{
- int pos = len - 1;
- while (pos >= 0) {
- counter[pos]++;
- if (counter[pos] != 0)
- break;
- pos--;
- }
-}
-
-VOID WpaDisassocApAndBlockAssoc(
- IN PVOID SystemSpecific1,
- IN PVOID FunctionContext,
- IN PVOID SystemSpecific2,
- IN PVOID SystemSpecific3)
-{
- RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
- MLME_DISASSOC_REQ_STRUCT DisassocReq;
-
- // disassoc from current AP first
- DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
- DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
- MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
-
- pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
- pAd->StaCfg.bBlockAssoc = TRUE;
-}
-
+#include "../../rt2870/sta/wpa.c"