wpa.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,629 行 · 第 1/5 页
C
1,629 行
}
// *(USHORT *)&pMsg->KeyDesc.Keyinfo = SWAP16(*(USHORT *)&pMsg->KeyDesc.Keyinfo);
#endif
// SECURE=1, REQUEST=0, ERROR=0
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
PeerGroupMsg2Action(pAdapter, pEntry, &Elem->Msg[LENGTH_802_11+Offset], (Elem->MsgLen-LENGTH_802_11-Offset));
else if (((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
&& (pEntry->WpaState >=AS_PTKINITDONE) && (pEntry->GTKState == REKEY_NEGOTIATING))
PeerGroupMsg2Action(pAdapter, pEntry, &Elem->Msg[LENGTH_802_11+Offset], (Elem->MsgLen-LENGTH_802_11-Offset));
else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
Wpa2PeerPairMsg4Action(pAdapter, pEntry, Elem);
}
else if (!(pKeyDesc->Keyinfo.Secure) && !(pKeyDesc->Keyinfo.Error) && !(pKeyDesc->Keyinfo.Request))
{
#ifdef BIG_ENDIAN
// recovery original byte order, before forward Elem to another routine
{
USHORT tmpKeyinfo;
NdisMoveMemory(&tmpKeyinfo, &pMsg->KeyDesc.Keyinfo, sizeof(USHORT));
tmpKeyinfo = SWAP16(tmpKeyinfo);
NdisMoveMemory(&pMsg->KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT));
}
// *(USHORT *)&pMsg->KeyDesc.Keyinfo = SWAP16(*(USHORT *)&pMsg->KeyDesc.Keyinfo);
#endif
// general 4-way handshake step // SECURE=0, REQUEST=0 , ERROR= 0
// Category 1
if (pEntry->WpaState == AS_PTKSTART)
PeerPairMsg2Action(pAdapter, pEntry, Elem);
else if (pEntry->WpaState == AS_PTKINIT_NEGOTIATING)
Wpa1PeerPairMsg4Action(pAdapter, pEntry, Elem);
}
else if (!(pKeyDesc->Keyinfo.Error) && (pKeyDesc->Keyinfo.Request))
{
// Category 3
if (pKeyDesc->Keyinfo.KeyType == GROUPKEY)
{
DBGPRINT(RT_DEBUG_TRACE, "REQUEST=1, ERROR=0, update group key\n");
GenRandom(pAdapter, pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GNonce, pEntry->ApIdx);
for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
{
if ((pAdapter->MacTab.Content[i].Valid == TRUE) && (pAdapter->MacTab.Content[i].WpaState == AS_PTKINITDONE)
&& (pAdapter->MacTab.Content[i].ApIdx == pEntry->ApIdx))
{
pAdapter->MacTab.Content[i].GTKState = REKEY_NEGOTIATING;
WPAHardTransmit(pAdapter, &pAdapter->MacTab.Content[i]);
}
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "REQUEST=1, ERROR= 0, update pairwise key\n");
pEntry->PairwiseKey.KeyLen = 0;
pEntry->Sst = SST_ASSOC;
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2))
pEntry->WpaState = AS_INITPMK;
else if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
pEntry->WpaState = AS_INITPSK;
pEntry->GTKState = REKEY_NEGOTIATING;
pEntry->RetryTimer.expires = jiffies + WPA_RETRY_EXEC_INTV;
pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
WPAStart4WayHS(pAdapter, pEntry);
}
}
else
{
//
}
}
}
VOID RTMPHandleSTAKey(
IN PRTMP_ADAPTER pAd,
IN PMAC_TABLE_ENTRY pEntry,
IN MLME_QUEUE_ELEM *Elem)
{
ULONG FrameLen = 0;
PUCHAR pOutBuffer = NULL;
UCHAR Header802_3[14];
EAPOL_PACKET Packet, EAPOLPKT;
PEAPOL_PACKET pSTAKey;
PHEADER_802_11 pHeader;
UCHAR Offset = 0;
ULONG MICMsgLen;
UCHAR DA[MAC_ADDR_LEN];
UCHAR Key_Data[512];
UCHAR key_length;
UCHAR mic[LEN_KEY_DESC_MIC];
UCHAR digest[80];
UCHAR temp[64];
PMAC_TABLE_ENTRY pDaEntry;
DBGPRINT(RT_DEBUG_TRACE, "==> RTMPHandleSTAKey\n");
if (!pEntry)
return;
if ((pEntry->WpaState != AS_PTKINITDONE))
{
DBGPRINT(RT_DEBUG_ERROR, "Not expect calling STAKey hand shaking here");
return;
}
pHeader = (PHEADER_802_11) Elem->Msg;
if (pHeader->FC.SubType & 0x08)
Offset += 2;
pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset];
// Check Replay Counter
if (!RTMPEqualMemory(pSTAKey->KeyDesc.RCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
{
DBGPRINT(RT_DEBUG_ERROR, "Replay Counter Different in STAKey handshake!! \n");
DBGPRINT(RT_DEBUG_ERROR, "Receive : %d %d %d %d \n", pSTAKey->KeyDesc.RCounter[0],pSTAKey->KeyDesc.RCounter[1],pSTAKey->KeyDesc.RCounter[2],pSTAKey->KeyDesc.RCounter[3]);
DBGPRINT(RT_DEBUG_ERROR, "Current : %d %d %d %d \n", pEntry->R_Counter[4],pEntry->R_Counter[5],pEntry->R_Counter[6],pEntry->R_Counter[7]);
return;
}
// Check MIC, if not valid, discard silently
NdisMoveMemory(DA, &pSTAKey->KeyDesc.Data[6], MAC_ADDR_LEN);
if (pSTAKey->KeyDesc.Keyinfo.KeyMic && pSTAKey->KeyDesc.Keyinfo.Secure && pSTAKey->KeyDesc.Keyinfo.Request)
{
pEntry->bDlsInit = TRUE;
DBGPRINT(RT_DEBUG_TRACE, "STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n",
pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
}
MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00);
MICMsgLen += LENGTH_EAPOL_H;
if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H))
{
DBGPRINT(RT_DEBUG_ERROR, "Receive wrong format EAPOL packets \n");
return;
}
// This is proprietary DLS protocol, it will be adhered when spec. is finished.
NdisZeroMemory(temp, 64);
NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
CountPTK(temp, temp, pAd->PortCfg.MBSSID[pEntry->ApIdx].Bssid, temp, pEntry->Addr, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_PTK);
DBGPRINT(RT_DEBUG_INFO, "PTK-%x %x %x %x %x %x %x %x \n",pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[0],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[1],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[2],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[3],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[4],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[5],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[6],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[7]);
NdisMoveMemory((PUCHAR)&EAPOLPKT, pSTAKey, MICMsgLen);
NdisZeroMemory(EAPOLPKT.KeyDesc.MIC, LEN_KEY_DESC_MIC);
if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
{
hmac_md5(pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, (PUCHAR)&EAPOLPKT, MICMsgLen, mic);
}
else
{
HMAC_SHA1((PUCHAR)&EAPOLPKT, MICMsgLen, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, mic);
}
if (!RTMPEqualMemory(pSTAKey->KeyDesc.MIC, mic, LEN_KEY_DESC_MIC))
{
DBGPRINT(RT_DEBUG_ERROR, "MIC Different in STAKey handshake!! \n");
return;
}
else
DBGPRINT(RT_DEBUG_TRACE, "MIC VALID in STAKey handshake!! \n");
// Receive init STA's STAKey Message-2, and terminate the handshake
if (pEntry->bDlsInit && !pSTAKey->KeyDesc.Keyinfo.Request)
{
pEntry->bDlsInit = FALSE;
DBGPRINT(RT_DEBUG_TRACE, "Receive init STA's STAKey Message-2, STAKey handshake finished \n");
return;
}
// Receive init STA's STAKey Message-2, and terminate the handshake
if (RTMPEqualMemory(&pSTAKey->KeyDesc.Data[2], OUI_WPA2_WEP40, 3))
{
DBGPRINT(RT_DEBUG_WARN, "Receive a STAKey message which not support currently, just drop it \n");
return;
}
do
{
pDaEntry = MacTableLookup(pAd, DA);
if (!pDaEntry)
break;
if ((pDaEntry->WpaState != AS_PTKINITDONE))
{
DBGPRINT(RT_DEBUG_ERROR, "Not expect calling STAKey hand shaking here \n");
break;
}
pOutBuffer = kmalloc(MAX_LEN_OF_EAP_HS, MEM_ALLOC_FLAG);
if(pOutBuffer == NULL)
break;
WPAMake8023Hdr(pAd, pDaEntry, Header802_3);
// Increment replay counter by 1
ADD_ONE_To_64BIT_VAR(pAd->PortCfg.R_Counter);
// 0. init Packet and Fill header
NdisZeroMemory(&Packet, sizeof(Packet));
Packet.ProVer = EAPOL_VER;
Packet.ProType = EAPOLKey;
Packet.Body_Len[1] = 0x5f;
// 1. Fill replay counter
NdisMoveMemory(pDaEntry->R_Counter, pAd->PortCfg.R_Counter, sizeof(pDaEntry->R_Counter));
NdisMoveMemory(Packet.KeyDesc.RCounter, pDaEntry->R_Counter, sizeof(pDaEntry->R_Counter));
// 2. Fill key version, keyinfo, key len
Packet.KeyDesc.Keyinfo.KeyDescVer= GROUP_KEY;
Packet.KeyDesc.Keyinfo.KeyType = GROUP_KEY;
Packet.KeyDesc.Keyinfo.Install = 1;
Packet.KeyDesc.Keyinfo.KeyAck = 1;
Packet.KeyDesc.Keyinfo.KeyMic = 1;
Packet.KeyDesc.Keyinfo.Secure = 1;
Packet.KeyDesc.Keyinfo.EKD = 1;
DBGPRINT(RT_DEBUG_TRACE, "STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n",
DA[0], DA[1], DA[2], DA[3], DA[4], DA[5]);
if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
{
Packet.KeyDesc.Type = WPA1_KEY_DESC;
DBGPRINT(RT_DEBUG_TRACE, "pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n");
}
else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
{
Packet.KeyDesc.Type = WPA2_KEY_DESC;
Packet.KeyDesc.DataLen[1] = 0;
DBGPRINT(RT_DEBUG_TRACE, "pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n");
}
Packet.KeyDesc.KeyLength[1] = LEN_TKIP_KEY;
Packet.KeyDesc.DataLen[1] = LEN_TKIP_KEY;
Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_TKIP;
if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
Packet.KeyDesc.KeyLength[1] = LEN_AES_KEY;
Packet.KeyDesc.DataLen[1] = LEN_AES_KEY;
Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_AES;
}
// Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard.
Key_Data[0] = 0xDD;
Key_Data[1] = 0x00; // Length (This field will be filled later)
Key_Data[2] = 0x00; // OUI
Key_Data[3] = 0x0C; // OUI
Key_Data[4] = 0x43; // OUI
Key_Data[5] = 0x02; // Data Type (STAKey Key Data Encryption)
// STAKey Data Encapsulation format
Key_Data[6] = 0x00; //Reserved
Key_Data[7] = 0x00; //Reserved
// STAKey MAC address
NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN); // initiator MAC address
// STAKey (Handle the difference between TKIP and AES-CCMP)
if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
Key_Data[1] = 0x1E; // 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey)
NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_KEY);
}
else
{
Key_Data[1] = 0x2E; // 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey)
NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TKIP_EK);
NdisMoveMemory(&Key_Data[14+LEN_TKIP_EK], pEntry->PairwiseKey.TxMic, LEN_TKIP_TXMICK);
NdisMoveMemory(&Key_Data[14+LEN_TKIP_EK+LEN_TKIP_TXMICK], pEntry->PairwiseKey.RxMic, LEN_TKIP_RXMICK);
}
key_length = Key_Data[1];
Packet.Body_Len[1] = key_length + 0x5f;
// This is proprietary DLS protocol, it will be adhered when spec. is finished.
NdisZeroMemory(temp, 64);
NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
CountPTK(temp, temp, pAd->PortCfg.MBSSID[pEntry->ApIdx].Bssid, temp, DA, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_PTK);
DBGPRINT(RT_DEBUG_TRACE, "PTK-0-%x %x %x %x %x %x %x %x \n",pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[0],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[1],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[2],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[3],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[4],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[5],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[6],pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK[7]);
NdisMoveMemory(Packet.KeyDesc.Data, Key_Data, key_length);
NdisZeroMemory(mic, sizeof(mic));
MakeOutgoingFrame(pOutBuffer, &FrameLen,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
// Calculate MIC
if (pDaEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
HMAC_SHA1(pOutBuffer, FrameLen, pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, digest);
NdisMoveMemory(Packet.KeyDesc.MIC, digest, LEN_KEY_DESC_MIC);
}
else
{
hmac_md5(pAd->PortCfg.MBSSID[pEntry->ApIdx].DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, mic);
NdisMoveMemory(Packet.KeyDesc.MIC, mic, LEN_KEY_DESC_MIC);
}
#ifdef BIG_ENDIAN
{
USHORT tmpKeyinfo;
NdisMoveMemory(&tmpKeyinfo, &Packet.KeyDesc.Keyinfo, sizeof(USHORT));
tmpKeyinfo = SWAP16(tmpKeyinfo);
NdisMoveMemory(&Packet.KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT));
}
#endif
// Fill frame
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(Header802_3), Header802_3,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
RTMPToWirelessSta(pAd, pOutBuffer, FrameLen);
kfree(pOutBuffer);
}while(FALSE);
DBGPRINT(RT_DEBUG_TRACE, "<== RTMPHandleSTAKey: FrameLen=%d\n", FrameLen);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?