📄 cmm_sanity.c
字号:
*/BOOLEAN PeerAuthSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr, OUT USHORT *pAlg, OUT USHORT *pSeq, OUT USHORT *pStatus, CHAR *pChlgText) { PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2); NdisMoveMemory(pAlg, &pFrame->Octet[0], 2); NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); if ((*pAlg == Ndis802_11AuthModeOpen)#ifdef LEAP_SUPPORT || (*pAlg == CISCO_AuthModeLEAP)#endif // LEAP_SUPPORT // ) { if (*pSeq == 1 || *pSeq == 2) { return TRUE; } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); return FALSE; } } else if (*pAlg == Ndis802_11AuthModeShared) { if (*pSeq == 1 || *pSeq == 4) { return TRUE; } else if (*pSeq == 2 || *pSeq == 3) { NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN); return TRUE; } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n")); return FALSE; } } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n")); return FALSE; }}/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */BOOLEAN MlmeAuthReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr, OUT ULONG *pTimeout, OUT USHORT *pAlg) { MLME_AUTH_REQ_STRUCT *pInfo; pInfo = (MLME_AUTH_REQ_STRUCT *)Msg; COPY_MAC_ADDR(pAddr, pInfo->Addr); *pTimeout = pInfo->Timeout; *pAlg = pInfo->Alg; if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)#ifdef LEAP_SUPPORT || (*pAlg == CISCO_AuthModeLEAP)#endif // LEAP_SUPPORT // ) && ((*pAddr & 0x01) == 0)) { return TRUE; } else { DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n")); return FALSE; }}/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */BOOLEAN MlmeAssocReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pApAddr, OUT USHORT *pCapabilityInfo, OUT ULONG *pTimeout, OUT USHORT *pListenIntv) { MLME_ASSOC_REQ_STRUCT *pInfo; pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg; *pTimeout = pInfo->Timeout; // timeout COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address *pCapabilityInfo = pInfo->CapabilityInfo; // capability info *pListenIntv = pInfo->ListenIntv; return TRUE;}/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */BOOLEAN PeerDisassocSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pReason) { PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); NdisMoveMemory(pReason, &pFrame->Octet[0], 2); return TRUE;}/* ======================================================================== Routine Description: Sanity check NetworkType (11b, 11g or 11a) Arguments: pBss - Pointer to BSS table. Return Value: Ndis802_11DS .......(11b) Ndis802_11OFDM24....(11g) Ndis802_11OFDM5.....(11a) IRQL = DISPATCH_LEVEL ========================================================================*/NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity( IN PBSS_ENTRY pBss){ NDIS_802_11_NETWORK_TYPE NetWorkType; UCHAR rate, i; NetWorkType = Ndis802_11DS; if (pBss->Channel <= 14) { // // First check support Rate. // for (i = 0; i < pBss->SupRateLen; i++) { rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) { continue; } else { // // Otherwise (even rate > 108) means Ndis802_11OFDM24 // NetWorkType = Ndis802_11OFDM24; break; } } // // Second check Extend Rate. // if (NetWorkType != Ndis802_11OFDM24) { for (i = 0; i < pBss->ExtRateLen; i++) { rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22)) { continue; } else { // // Otherwise (even rate > 108) means Ndis802_11OFDM24 // NetWorkType = Ndis802_11OFDM24; break; } } } } else { NetWorkType = Ndis802_11OFDM5; } if (pBss->HtCapabilityLen != 0) { if (NetWorkType == Ndis802_11OFDM5) NetWorkType = Ndis802_11OFDM5_N; else NetWorkType = Ndis802_11OFDM24_N; } return NetWorkType;} /* ========================================================================== Description: WPA message sanity check Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */BOOLEAN PeerWpaMessageSanity( IN PRTMP_ADAPTER pAd, IN PEAPOL_PACKET pMsg, IN ULONG MsgLen, IN UCHAR MsgType, IN PUCHAR pMIC, IN MAC_TABLE_ENTRY *pEntry){ UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE]; BOOLEAN bReplayDiff = FALSE; BOOLEAN bWPA2 = FALSE; KEY_INFO EapolKeyInfo; UCHAR GroupKeyIndex = 0; NdisZeroMemory(mic, sizeof(mic)); NdisZeroMemory(digest, sizeof(digest)); NdisZeroMemory(KEYDATA, sizeof(KEYDATA)); NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo)); NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));#ifdef BIG_ENDIAN *((USHORT *)&EapolKeyInfo) = SWAP16(*((USHORT *)&EapolKeyInfo));#endif // BIG_ENDIAN // // Choose WPA2 or not if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) bWPA2 = TRUE; // 0. Check MsgType if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) { DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType)); return FALSE; } // 1. Replay counter check if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant { // First validate replay counter, only accept message with larger replay counter. // Let equal pass, some AP start with all zero replay counter UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) && (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0)) { bReplayDiff = TRUE; } } else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator { // check Replay Counter coresponds to MSG from authenticator, otherwise discard if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) { bReplayDiff = TRUE; } } // Replay Counter different condition if (bReplayDiff) { // send wireless event - for replay counter different if (pAd->CommonCfg.bWirelessEvent) RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry); if (MsgType < EAPOL_GROUP_MSG_1) { DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType)); } else { DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); } hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY); return FALSE; } // 2. Verify MIC except Pairwise Msg1 if (MsgType != EAPOL_PAIR_MSG_1) { NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP { hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic); } else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES { HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } if (!NdisEqualMemory(pMIC, mic, LEN_KEY_DESC_MIC)) { // send wireless event - for MIC different if (pAd->CommonCfg.bWirelessEvent) RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry); if (MsgType < EAPOL_GROUP_MSG_1) { DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType)); } else { DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); } hex_dump("Received MIC", pMIC, LEN_KEY_DESC_MIC); hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC); return FALSE; } } // Extract the context of the Key Data field if it exist // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted. // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. if (pMsg->KeyDesc.KeyDataLen[1] > 0) { // Decrypt this field if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) { if(pEntry->WepStatus == Ndis802_11Encryption3Enabled) { // AES AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData); } else { INT i; UCHAR Key[32]; // Decrypt TKIP GTK // Construct 32 bytes RC4 Key NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16); NdisMoveMemory(&Key[16], &pEntry->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, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]); } if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) GroupKeyIndex = EapolKeyInfo.KeyIndex; } else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) { NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]); } else { DBGPRINT(RT_DEBUG_INFO, ("The Key Data Length should be zero !!!\n")); return TRUE; } // Parse Key Data field to // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry)) { return FALSE; } } return TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -