📄 wpa.c
字号:
// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -