wpa.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,629 行 · 第 1/5 页
C
1,629 行
/*
==========================================================================
Description:
This is a function to initilize 4way handshake
Return:
==========================================================================
*/
VOID WPAStart4WayHS(
IN PRTMP_ADAPTER pAdapter,
IN MAC_TABLE_ENTRY *pEntry)
{
ULONG FrameLen = 0;
UCHAR *OutBuffer = NULL;
UCHAR Header802_3[14];
EAPOL_PACKET Packet;
DBGPRINT(RT_DEBUG_TRACE, "==>WPAStart4WayHS\n");
do
{
if (!pEntry)
break;
if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK))
{
DBGPRINT(RT_DEBUG_ERROR, "Not expect calling WPAStart4WayHS here ");
break;
}
OutBuffer = kmalloc(MAX_LEN_OF_EAP_HS, MEM_ALLOC_FLAG);
if(OutBuffer == NULL)
break;
WPAMake8023Hdr(pAdapter, pEntry, Header802_3);
// Increment replay counter by 1
ADD_ONE_To_64BIT_VAR(pAdapter->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(pEntry->R_Counter, pAdapter->PortCfg.R_Counter, sizeof(pEntry->R_Counter));
NdisMoveMemory(Packet.KeyDesc.RCounter, pEntry->R_Counter, sizeof(pEntry->R_Counter));
// 2. Fill key version, keyinfo, key len
Packet.KeyDesc.Keyinfo.KeyType = PAIRWISEKEY;
Packet.KeyDesc.Keyinfo.KeyAck = 1;
DBGPRINT(RT_DEBUG_TRACE, "STA from %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]);
DBGPRINT(RT_DEBUG_TRACE, "PMK = %02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x\n",
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[0],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[1],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[2],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[3],
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[4],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[5],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[6],pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK[7]);
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
{
Packet.KeyDesc.Type = WPA1_KEY_DESC;
Packet.KeyDesc.DataLen[1] = 0;
DBGPRINT(RT_DEBUG_TRACE, "pEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n");
}
else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
{
Packet.KeyDesc.Type = WPA2_KEY_DESC;
Packet.KeyDesc.DataLen[1] = 0;
// PMKID match, then start 4-way HS directly
if (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)
{
Packet.KeyDesc.Data[0] = 0xDD;
Packet.KeyDesc.Data[2] = 0x00;
Packet.KeyDesc.Data[3] = 0x0F;
Packet.KeyDesc.Data[4] = 0xAC;
Packet.KeyDesc.Data[5] = 0x04;
NdisMoveMemory(&Packet.KeyDesc.Data[6], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMKIDCache.BSSIDInfo[pEntry->PMKID_CacheIdx].PMKID, LEN_PMKID);
NdisMoveMemory(&pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK, &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMKIDCache.BSSIDInfo[pEntry->PMKID_CacheIdx].PMK, PMK_LEN);
Packet.KeyDesc.Data[1] = 0x14;// 4+2+LEN_PMKID
Packet.KeyDesc.DataLen[1] += 6 + LEN_PMKID;
Packet.Body_Len[1] += 6 + LEN_PMKID;
}
DBGPRINT(RT_DEBUG_TRACE, "pEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n");
}
if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
{
Packet.KeyDesc.KeyLength[1] = LEN_TKIP_KEY;
Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_TKIP;
}
else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
Packet.KeyDesc.KeyLength[1] = LEN_AES_KEY;
Packet.KeyDesc.Keyinfo.KeyDescVer = DESC_TYPE_AES;
}
#ifdef BIG_ENDIAN
{
USHORT tmpKeyinfo;
NdisMoveMemory(&tmpKeyinfo, &Packet.KeyDesc.Keyinfo, sizeof(USHORT));
tmpKeyinfo = SWAP16(tmpKeyinfo);
NdisMoveMemory(&Packet.KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT));
}
// *(USHORT *)&Packet.KeyDesc.Keyinfo = SWAP16(*(USHORT *)&Packet.KeyDesc.Keyinfo);
#endif
// 3. Fill Anonce
GenRandom(pAdapter, pEntry->ANonce, pEntry->ApIdx);
NdisMoveMemory(Packet.KeyDesc.Nonce, pEntry->ANonce, sizeof(pEntry->ANonce));
MakeOutgoingFrame(OutBuffer, &FrameLen,
sizeof(Header802_3), Header802_3,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
RTMPToWirelessSta(pAdapter, OutBuffer, FrameLen);
mod_timer(&pEntry->RetryTimer, pEntry->RetryTimer.expires);
// Should start from 1, init is 0
pEntry->ReTryCounter++;
pEntry->RetryTimerRunning = TRUE;
pEntry->WpaState = AS_PTKSTART;
kfree(OutBuffer);
}while(FALSE);
DBGPRINT(RT_DEBUG_TRACE, "<== WPAStart4WayHS:pEntry->WpaState=%d, FrameLen=%d\n",pEntry->WpaState,FrameLen);
}
/*
==========================================================================
Description:
When receiving the second packet of 4-way pairwisekey handshake.
Return:
==========================================================================
*/
VOID PeerPairMsg2Action(
IN PRTMP_ADAPTER pAdapter,
IN MAC_TABLE_ENTRY *pEntry,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR *mpool, *PTK, *digest, *Key_Data, *pRc4GTK;
UCHAR mic[LEN_KEY_DESC_MIC], SNonce[LEN_KEY_DESC_NONCE];
ULONG FrameLen = 0;
UCHAR *OutBuffer = NULL;
USHORT MICMsgLen, MICOffset;
PUCHAR pSA;
UCHAR Header802_3[LENGTH_802_3];
EAPOL_PACKET Packet;
PEAPOL_PACKET pMsg2;
PHEADER_802_11 pHeader;
DBGPRINT(RT_DEBUG_TRACE, "PeerPairMsg2Action ===>\n");
if (!pEntry)
return;
// check Entry in valid State
if (pEntry->WpaState < AS_PTKSTART)
return;
mpool = kmalloc(4096, MEM_ALLOC_FLAG); // allocate memory
if (mpool == NULL)
return;
/* OutBuffer Len = MAX_LEN_OF_EAP_HS */
OutBuffer = (UCHAR *) ROUND_UP(mpool, 4);
/* PTK Len = 80 */
PTK = (UCHAR *) ROUND_UP(OutBuffer+MAX_LEN_OF_EAP_HS, 4);
/* digest Len = 80 */
digest =(UCHAR *) ROUND_UP(PTK+80, 4);
/* pRc4GTK Len = 512 */
pRc4GTK = (UCHAR *) ROUND_UP(digest+80, 4);
/* Key_Data Len = 512 */
Key_Data = (UCHAR *) ROUND_UP(pRc4GTK+512, 4);
do
{
// Save Data Length to pDesc for receiving packet, then put in outgoing frame Data Len fields.
pHeader = (PHEADER_802_11) Elem->Msg;
if (pHeader->FC.SubType & 0x08)
{
pMsg2 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + 2];
}
else
{
pMsg2 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
}
// 1. check Replay Counter coresponds to MSG1., otherwise discard
if (!RTMPEqualMemory(pMsg2->KeyDesc.RCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
{
DBGPRINT(RT_DEBUG_ERROR, "Replay Counter Different in Msg 2 of 4-way handshake !! \n");
DBGPRINT(RT_DEBUG_ERROR, "Receive : %d %d %d %d %d %d %d %d \n", pMsg2->KeyDesc.RCounter[0],pMsg2->KeyDesc.RCounter[1],\
pMsg2->KeyDesc.RCounter[2],pMsg2->KeyDesc.RCounter[3],pMsg2->KeyDesc.RCounter[4],pMsg2->KeyDesc.RCounter[5],pMsg2->KeyDesc.RCounter[6],pMsg2->KeyDesc.RCounter[7]);
DBGPRINT(RT_DEBUG_ERROR, "Current : %d %d %d %d %d %d %d %d \n",pEntry->R_Counter[0],pEntry->R_Counter[1],pEntry->R_Counter[2],pEntry->R_Counter[3],\
pEntry->R_Counter[4],pEntry->R_Counter[5],pEntry->R_Counter[6],pEntry->R_Counter[7]);
break;
}
// 2. Derive necessary info for counting PTK and thus count PTK
MICMsgLen = pMsg2->Body_Len[1] | ((pMsg2->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");
break;
}
NdisMoveMemory(SNonce, pMsg2->KeyDesc.Nonce, LEN_KEY_DESC_NONCE);
pSA = pEntry->Addr;
CountPTK(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].PMK, pEntry->ANonce, pAdapter->PortCfg.MBSSID[pEntry->ApIdx].Bssid, SNonce, pSA, PTK, LEN_PTK);
NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
DBGPRINT(RT_DEBUG_TRACE, "PTK-%x %x %x %x %x %x %x %x \n",PTK[0],PTK[1],PTK[2],PTK[3],PTK[4],PTK[5],PTK[6],PTK[7]);
DBGPRINT(RT_DEBUG_TRACE, "ANonce1-%x %x %x %x %x %x %x %x \n",pEntry->ANonce[0],pEntry->ANonce[1],pEntry->ANonce[2],pEntry->ANonce[3],pEntry->ANonce[4],pEntry->ANonce[5],pEntry->ANonce[6],pEntry->ANonce[7]);
DBGPRINT(RT_DEBUG_TRACE, "ANonce2-%x %x %x %x %x %x %x %x \n",pEntry->ANonce[8],pEntry->ANonce[9],pEntry->ANonce[10],pEntry->ANonce[11],pEntry->ANonce[12],pEntry->ANonce[13],pEntry->ANonce[14],pEntry->ANonce[15]);
// 3. verify MSG2 MIC, If not valid, discard.
MICOffset = sizeof(EAPOL_PACKET)-MAX_LEN_OF_RSNIE-2-LEN_KEY_DESC_MIC;
NdisMoveMemory(OutBuffer, pMsg2, MICMsgLen);
NdisZeroMemory((OutBuffer+MICOffset), LEN_KEY_DESC_MIC);
if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
{
hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, MICMsgLen, mic);
}
else
{
HMAC_SHA1(OutBuffer, MICMsgLen, PTK, LEN_EAP_MICK, digest);
NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
}
if (!RTMPEqualMemory((PUCHAR)pMsg2+MICOffset, mic, LEN_KEY_DESC_MIC))
{
DBGPRINT(RT_DEBUG_ERROR, "MIC Different in Msg 2 of 4-way handshake!! \n");
break;
}
else
DBGPRINT(RT_DEBUG_TRACE, "MIC VALID in Msg 2 of 4-way handshake!! \n");
// 4. check RSN IE, if not match, send MLME-DEAUTHENTICATE.
if (!RTMPEqualMemory(&pMsg2->KeyDesc.Data[2], pEntry->RSN_IE, pEntry->RSNIE_Len))
{
DBGPRINT(RT_DEBUG_ERROR, "RSN_IE Different in Msg 2 of 4-way handshake!! \n");
DBGPRINT(RT_DEBUG_ERROR, "Receive : %x %x %x %x ...\n",pMsg2->KeyDesc.Data[2], pMsg2->KeyDesc.Data[3],pMsg2->KeyDesc.Data[4],pMsg2->KeyDesc.Data[5] );
DBGPRINT(RT_DEBUG_ERROR, "Current : %x %x %x %x ...\n",pEntry->RSN_IE[0], pEntry->RSN_IE[1],pEntry->RSN_IE[2],pEntry->RSN_IE[3] );
break;
}
else
DBGPRINT(RT_DEBUG_TRACE, "RSN_IE VALID in Msg 2 of 4-way handshake!! \n");
pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
// Increment replay counter by 1
ADD_ONE_To_64BIT_VAR(pAdapter->PortCfg.R_Counter);
NdisMoveMemory(pEntry->R_Counter, pAdapter->PortCfg.R_Counter, sizeof(pEntry->R_Counter));
// 5. CONSTRUCT msg3
// 5-0. Init Packet and Fill header
NdisZeroMemory(&Packet, sizeof(Packet));
Packet.ProVer = EAPOL_VER;
Packet.ProType = EAPOLKey;
// Fill replay counter
NdisMoveMemory(Packet.KeyDesc.RCounter, pEntry->R_Counter, sizeof(pEntry->R_Counter));
// Fill key version, keyinfo, key len
Packet.KeyDesc.Keyinfo.KeyMic = 1;
Packet.KeyDesc.Keyinfo.KeyType = PAIRWISEKEY;
Packet.KeyDesc.Keyinfo.Install = 1;
Packet.KeyDesc.Keyinfo.KeyAck = 1;
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
{
Packet.KeyDesc.Type = WPA1_KEY_DESC;
Packet.KeyDesc.DataLen[1] = 0;
}
else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
{
Packet.KeyDesc.Type = WPA2_KEY_DESC;
Packet.KeyDesc.DataLen[1] = 0;
Packet.KeyDesc.Keyinfo.EKD = 1;
Packet.KeyDesc.Keyinfo.Secure = 1;
}
if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
{
Packet.KeyDesc.KeyLength[1] = LEN_TKIP_KEY;
}
else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
Packet.KeyDesc.KeyLength[1] = LEN_AES_KEY;
}
Packet.KeyDesc.Keyinfo.KeyDescVer =
(((pEntry->WepStatus == Ndis802_11Encryption3Enabled) || (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
#ifdef BIG_ENDIAN
{
USHORT tmpKeyinfo;
NdisMoveMemory(&tmpKeyinfo, &Packet.KeyDesc.Keyinfo, sizeof(USHORT));
tmpKeyinfo = SWAP16(tmpKeyinfo);
NdisMoveMemory(&Packet.KeyDesc.Keyinfo, &tmpKeyinfo, sizeof(USHORT));
}
// *(USHORT *)&Packet.KeyDesc.Keyinfo = SWAP16(*(USHORT *)&Packet.KeyDesc.Keyinfo);
#endif
// 5-3, Fill in Data, Data Len
NdisMoveMemory(Packet.KeyDesc.Nonce, pEntry->ANonce, sizeof(pEntry->ANonce));
NdisZeroMemory(Packet.KeyDesc.MIC, sizeof(Packet.KeyDesc.MIC));
if ((pEntry->AuthMode == Ndis802_11AuthModeWPA) || (pEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
{
Packet.KeyDesc.Data[0] = IE_WPA;
Packet.KeyDesc.Data[1] = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[0];
Packet.KeyDesc.DataLen[1] = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[0] + 2;
Packet.Body_Len[1] = 93 + 2 + 2 + pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[0];
NdisMoveMemory(&Packet.KeyDesc.Data[2], pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0], pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[0]);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?