📄 cmm_wpa.c
字号:
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( IN PRTMP_ADAPTER pAd, IN UCHAR ElementID, IN UINT AuthMode, IN UCHAR apidx, OUT PUCHAR pRsnIe, OUT UCHAR *rsn_len){ RSNIE_AUTH *pRsnie_auth; UCHAR AkmCnt = 1; // default as 1 pRsnie_auth = (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(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( IN PRTMP_ADAPTER pAd, IN UCHAR ElementID, IN UCHAR apidx, OUT PUCHAR pRsnIe, OUT UCHAR *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( IN PRTMP_ADAPTER pAd, IN UINT AuthMode, IN UINT WepStatus, IN UCHAR apidx){ PUCHAR pRsnIe = NULL; // primary RSNIE UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE UCHAR PrimaryRsnie; BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different UCHAR p_offset; WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode rsnielen_cur_p = NULL; rsnielen_ex_cur_p = NULL; {#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) {#ifdef WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { if (AuthMode < Ndis802_11AuthModeWPA) return; } else#endif // WPA_SUPPLICANT_SUPPORT // { // 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; }#endif // CONFIG_STA_SUPPORT // } // 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( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN PUCHAR pData, IN ULONG DataByteCount, IN UCHAR FromWhichBSSID){ ULONG 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 ==========================================================================*/PSTRING 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( IN PRTMP_ADAPTER pAd, IN PUCHAR pData, IN UCHAR DataLen, IN MAC_TABLE_ENTRY *pEntry, 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 ((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( IN PRTMP_ADAPTER pAd, IN PUCHAR pKeyData, IN UCHAR KeyDataLen, IN UCHAR GroupKeyIndex, IN UCHAR MsgType, IN BOOLEAN bWPA2, IN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -