📄 cmm_wpa.c
字号:
MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); RTMPToWirelessSta(pAd, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)&EAPOLPKT, CONV_ARRARY_TO_UINT16(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. Initilize 2-way groupkey handshake following. Return: ==========================================================================*/VOID PeerPairMsg4Action( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry, IN MLME_QUEUE_ELEM *Elem) { PEAPOL_PACKET pMsg4; PHEADER_802_11 pHeader; UINT MsgLen; BOOLEAN Cancelled; UCHAR 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(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2 ) ) break; if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING) break; // pointer to 802.11 header pHeader = (PHEADER_802_11)Elem->Msg; // skip 802.11_header(24-byte) and LLC_header(8) pMsg4 = (PEAPOL_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(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, (UCHAR)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( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry) { UCHAR Header802_3[14]; UCHAR TxTsc[6]; EAPOL_PACKET EAPOLPKT; UCHAR group_cipher = Ndis802_11WEPDisabled; UCHAR default_key = 0; PUINT8 gnonce_ptr = NULL; PUINT8 gtk_ptr = NULL; PUINT8 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(EAPOL_PACKET)); ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_1, default_key, (UCHAR *)gnonce_ptr, TxTsc, (UCHAR *)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, (PUCHAR)&EAPOLPKT, CONV_ARRARY_TO_UINT16(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( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry, IN MLME_QUEUE_ELEM *Elem) { UCHAR Header802_3[14]; EAPOL_PACKET EAPOLPKT; PEAPOL_PACKET pGroup; UINT MsgLen; BOOLEAN Cancelled; UCHAR default_key = 0; UCHAR group_cipher = Ndis802_11WEPDisabled; PUINT8 pCurrentAddr = NULL; DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n")); if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) return;#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pCurrentAddr = pAd->CurrentAddress; group_cipher = pAd->StaCfg.GroupCipher; default_key = pAd->StaCfg.DefaultKeyId; } #endif // CONFIG_STA_SUPPORT // // 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]; 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(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;#ifdef CONFIG_STA_SUPPORT STA_PORT_SECURED(pAd); // Indicate Connected for GUI pAd->IndicateMediaState = NdisMediaStateConnected;#endif // CONFIG_STA_SUPPORT // 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), (PUCHAR)&EAPOLPKT, CONV_ARRARY_TO_UINT16(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( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry, IN VOID *Msg, IN UINT MsgLen) { UINT Len; PUCHAR pData; BOOLEAN Cancelled; PEAPOL_PACKET pMsg2; UCHAR 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(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2)) break; if (pEntry->WpaState != AS_PTKINITDONE) break; pData = (PUCHAR)Msg; pMsg2 = (PEAPOL_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 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;}/* ======================================================================== 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: UCHAR *key, - the key material for HMAC_SHA1 use INT key_len - the length of key UCHAR *prefix - a prefix label INT prefix_len - the length of the label UCHAR *data - a specific data with variable length INT data_len - the length of a specific data INT len - the output lenght Return Value: UCHAR *output - the calculated result Note: 802.11i-2004 Annex H.3 ========================================================================*/VOID PRF( IN UCHAR *key, IN INT key_len, IN UCHAR *prefix, IN INT prefix_len, IN UCHAR *data, IN INT data_len, OUT UCHAR *output, IN INT len){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -