wpa.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,629 行 · 第 1/5 页
C
1,629 行
// 5-4, First make a frame for Counting MIC.
MakeOutgoingFrame(OutBuffer, &FrameLen,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
NdisZeroMemory(mic, sizeof(mic));
// 5-5, count MIC
if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
UCHAR digest[80];
HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
}
else
{
hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
}
NdisMoveMemory(&Packet.KeyDesc.MIC, mic, LEN_KEY_DESC_MIC);
}
else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
{
UCHAR GTK[TKIP_GTK_LENGTH],/*pRc4GTK[512],*/ mic[LEN_KEY_DESC_MIC];
UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)], /*Key_Data[512],*/ key_length, RSNIE_Len;
NdisMoveMemory(Packet.KeyDesc.RSC, pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].TxTsc, 6);
CountGTK(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GMK, (UCHAR*)pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GNonce, pAdapter->PortCfg.MBSSID[pEntry->ApIdx].Bssid, GTK, TKIP_GTK_LENGTH);
NdisMoveMemory(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].Key, GTK, LEN_TKIP_EK);
NdisMoveMemory(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].TxMic, >K[16], LEN_TKIP_TXMICK);
NdisMoveMemory(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].RxMic, >K[24], LEN_TKIP_RXMICK);
DBGPRINT(RT_DEBUG_INFO, "WPA2 Group Key ID = %d\n", pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId);
DBGPRINT(RT_DEBUG_INFO, "G_Key :%x %x %x %x %x %x %x %x \n",GTK[0],GTK[1],GTK[2],GTK[3],GTK[4],GTK[5],GTK[6],GTK[7]);
DBGPRINT(RT_DEBUG_INFO, " %x %x %x %x %x %x %x %x \n",GTK[8],GTK[9],GTK[10],GTK[11],GTK[12],GTK[13],GTK[14],GTK[15]);
DBGPRINT(RT_DEBUG_INFO, "TX Mic:%x %x %x %x %x %x %x %x \n",GTK[16],GTK[17],GTK[18],GTK[19],GTK[20],GTK[21],GTK[22],GTK[23]);
DBGPRINT(RT_DEBUG_INFO, "RX Mic:%x %x %x %x %x %x %x %x \n",GTK[24],GTK[25],GTK[26],GTK[27],GTK[28],GTK[29],GTK[30],GTK[31]);
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GroupKeyWepStatus == Ndis802_11Encryption2Enabled)
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].CipherAlg = CIPHER_AES;
else
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].CipherAlg = CIPHER_NONE;
// install Group Key to MAC ASIC
AsicAddSharedKeyEntry(
pAdapter,
pEntry->ApIdx,
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId,
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].CipherAlg,
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].Key,
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].TxMic,
pAdapter->PortCfg.MBSSID[pEntry->ApIdx].SharedKey[pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId].RxMic);
NdisZeroMemory(Key_Data, 512); //sizeof(Key_Data));
if ((pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK) ||
(pAdapter->PortCfg.MBSSID[pEntry->ApIdx].AuthMode == Ndis802_11AuthModeWPA1WPA2))
{
RSNIE_Len = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[1];
NdisMoveMemory(&Key_Data[2], pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[1], RSNIE_Len);
}
else
{
RSNIE_Len = pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSNIE_Len[0];
NdisMoveMemory(&Key_Data[2], &pAdapter->PortCfg.MBSSID[pEntry->ApIdx].RSN_IE[0], RSNIE_Len);
}
Packet.Body_Len[1] = 2+RSNIE_Len;
Key_Data[0] = IE_WPA2;
Key_Data[1] = RSNIE_Len;
// Key Data Encapsulation format
Key_Data[2+RSNIE_Len+0] = 0xDD;
Key_Data[2+RSNIE_Len+2] = 0x00;
Key_Data[2+RSNIE_Len+3] = 0x0F;
Key_Data[2+RSNIE_Len+4] = 0xAC;
Key_Data[2+RSNIE_Len+5] = 0x01;
// GTK Key Data Encapsulation format
Key_Data[2+RSNIE_Len+6] = (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].DefaultKeyId & 0x03);
Key_Data[2+RSNIE_Len+7] = 0x00;
// handle the difference between TKIP and AES-CCMP
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
{
Key_Data[2+RSNIE_Len+1] = 0x16;// 4+2+16(OUI+GTK+GTKKEY)
NdisMoveMemory(&Key_Data[2+RSNIE_Len+8], GTK, LEN_AES_KEY);
Packet.Body_Len[1] += 8+LEN_AES_KEY;
}
else
{
Key_Data[2+RSNIE_Len+1] = 0x26;// 4+2+32(OUI+GTK+GTKKEY)
NdisMoveMemory(&Key_Data[2+RSNIE_Len+8], GTK, TKIP_GTK_LENGTH);
Packet.Body_Len[1] += 8+TKIP_GTK_LENGTH;
}
// Still dont know why, but if not append will occur "GTK not include in MSG3"
// Patch for compatibility between zero config and funk
if (pAdapter->PortCfg.MBSSID[pEntry->ApIdx].GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
{
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH] = 0xDD;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+1] = 0;
Packet.Body_Len[1] += 2;
}
else
{
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH] = 0xDD;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+1] = 0;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+2] = 0;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+3] = 0;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+4] = 0;
Key_Data[2+RSNIE_Len+8+TKIP_GTK_LENGTH+5] = 0;
Packet.Body_Len[1] += 6;
}
key_length = Packet.Body_Len[1];
Packet.KeyDesc.DataLen[1] = key_length;
Packet.Body_Len[1] += 93 + 2;
NdisZeroMemory(mic, sizeof(mic));
// count MIC
if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
{
AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, key_length, pRc4GTK);
// AES wrap function will grow 8 bytes in length
NdisMoveMemory(Packet.KeyDesc.Data, pRc4GTK, (key_length + 8));
Packet.Body_Len[1] += 8;
Packet.KeyDesc.DataLen[1] += 8;
MakeOutgoingFrame(OutBuffer, &FrameLen,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
HMAC_SHA1(OutBuffer, FrameLen, pEntry->PTK, LEN_EAP_MICK, digest);
NdisMoveMemory(Packet.KeyDesc.MIC, digest, LEN_KEY_DESC_MIC);
}
else
{
// PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
// put TxTsc in Key RSC field
pAdapter->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
// ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
NdisMoveMemory(ekey, Packet.KeyDesc.IV, LEN_KEY_DESC_IV);
NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], LEN_EAP_EK);
ARCFOUR_INIT(&pAdapter->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
pAdapter->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAdapter->PrivateInfo.FCSCRC32, Key_Data, key_length);
WPAARCFOUR_ENCRYPT(&pAdapter->PrivateInfo.WEPCONTEXT, pRc4GTK,Key_Data, key_length);
NdisMoveMemory(Packet.KeyDesc.Data, pRc4GTK, key_length);
// make a frame for Countint MIC,
MakeOutgoingFrame(OutBuffer, &FrameLen,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
hmac_md5(pEntry->PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
NdisMoveMemory(Packet.KeyDesc.MIC, mic, LEN_KEY_DESC_MIC);
}
}
// 5-6, Make outgoing frame
WPAMake8023Hdr(pAdapter, pEntry, Header802_3);
MakeOutgoingFrame(OutBuffer, &FrameLen,
LENGTH_802_3, Header802_3,
Packet.Body_Len[1] + 4, &Packet,
END_OF_ARGS);
DBGPRINT(RT_DEBUG_TRACE, "RTMPToWirelessSta : ETHTYPE = %x %x FrameLen = %d! \n",Header802_3[12],Header802_3[13],FrameLen);
RTMPToWirelessSta(pAdapter, OutBuffer, FrameLen);
// Should start from 1, init is 0
pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
pEntry->RetryTimer.expires = jiffies + PEER_MSG3_RETRY_EXEC_INTV;
pEntry->RetryTimerRunning = TRUE;
mod_timer(&pEntry->RetryTimer, pEntry->RetryTimer.expires);
DBGPRINT(RT_DEBUG_TRACE, "Send Msg3 and setup timeout timer\n");
pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
}while(FALSE);
kfree(mpool);
}
/*
==========================================================================
Description:
countermeasures active attack timer execution
Return:
==========================================================================
*/
VOID CMTimerExec(
IN unsigned long data)
{
UINT i, j=0, apidx;
RTMP_ADAPTER *pAdapter = (RTMP_ADAPTER *)data;
for (apidx = 0; apidx < pAdapter->PortCfg.BssidNum; apidx++)
{
pAdapter->PortCfg.MBSSID[apidx].BANClass3Data = FALSE;
}
for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
{
if ((pAdapter->MacTab.Content[i].Valid == TRUE) && (pAdapter->MacTab.Content[i].CMTimerRunning == TRUE))
{
pAdapter->MacTab.Content[i].CMTimerRunning = FALSE;
j++;
}
}
if (j > 1)
DBGPRINT(RT_DEBUG_ERROR, "Find more than one entry which generated MIC Fail .. \n");
pAdapter->PortCfg.CMTimerRunning = FALSE;
}
VOID WPARetryExec(
IN unsigned long data)
{
MAC_TABLE_ENTRY *pEntry = (PMAC_TABLE_ENTRY) data;
if ((pEntry) && (pEntry->RetryTimerRunning == TRUE))
{
RTMP_ADAPTER *pAdapter = (PRTMP_ADAPTER)pEntry->pAd;
// Turn off the retry flag first
pEntry->RetryTimerRunning = FALSE;
DBGPRINT(RT_DEBUG_TRACE, "WPARetryExec - ReTryCounter=%d, WpaState=%d \n", pEntry->ReTryCounter, pEntry->WpaState);
switch (pEntry->AuthMode)
{
case Ndis802_11AuthModeWPA:
case Ndis802_11AuthModeWPAPSK:
case Ndis802_11AuthModeWPA2:
case Ndis802_11AuthModeWPA2PSK:
// 1. GTK already retried, give up and disconnect client.
if (pEntry->ReTryCounter > (GRP_HS_RETRY_TIMER_CTR + 1))
{
// Deauthenticate and delete timer and entry
DisAssocAction(pAdapter, pEntry, SUBTYPE_DISASSOC, REASON_GROUP_KEY_UPDATE_TIMEOUT);
DBGPRINT(RT_DEBUG_TRACE, "Delete client after GTK retry failed\n");
}
// 2. Retry GTK.
else if (pEntry->ReTryCounter >= GRP_HS_RETRY_TIMER_CTR)
{
DBGPRINT(RT_DEBUG_TRACE, "ReInitilize 2-way group-key Handshake ===> \n");
WPAHardTransmit( pAdapter, pEntry);
pEntry->RetryTimer.expires = jiffies + WPA_RETRY_EXEC_INTV;
mod_timer(&pEntry->RetryTimer, pEntry->RetryTimer.expires);
pEntry->ReTryCounter++;
pEntry->RetryTimerRunning = TRUE;
}
// 3. 4-way message 1 retried more than three times. Disconnect client
else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3))
{
// Deauthenticate and delete timer and entry
DisAssocAction(pAdapter, pEntry, SUBTYPE_DEAUTH, REASON_UNSPECIFY);
DBGPRINT(RT_DEBUG_TRACE, "Delete client after 3 retries of message_1 \n");
}
// 4. Retry 4 way message 1, the last try, the timeout is 5 sec for EAPOL-Start
else if (pEntry->ReTryCounter == (PEER_MSG1_RETRY_TIMER_CTR + 3))
{
DBGPRINT(RT_DEBUG_TRACE, "Message 1 time out, the last retry\n");
pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
pEntry->WpaState = AS_INITPSK;
pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
pEntry->RetryTimer.expires = jiffies + (5 * HZ);
WPAStart4WayHS(pAdapter, pEntry);
}
// 4. Retry 4 way message 1
else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3))
{
DBGPRINT(RT_DEBUG_TRACE, "Message 1 time out, retry it\n");
pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
pEntry->WpaState = AS_INITPSK;
pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
pEntry->RetryTimer.expires = jiffies + WPA_RETRY_EXEC_INTV;
WPAStart4WayHS(pAdapter, pEntry);
}
break;
default:
break;
}
}
}
/*
==========================================================================
Description:
When receiving the last packet of 4-way pairwisekey handshake.
Initilize 2-way groupkey handshake following.
Return:
==========================================================================
*/
VOID Wpa1PeerPairMsg4Action(
IN PRTMP_ADAPTER pAdapter,
IN MAC_TABLE_ENTRY *pEntry,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR mic[LEN_KEY_DESC_MIC], digest[80];
ULONG MICMsgLen;
EAPOL_PACKET EAPOLPKT;
PEAPOL_PACKET pMsg4;
NDIS_STATUS Status;
PHEADER_802_11 pHeader;
UCHAR Offset = 0;
DBGPRINT(RT_DEBUG_TRACE, "WpaEAPOL Peer Pair Msg4 Action ===>\n");
if (!pEntry)
return;
if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
return;
pHeader = (PHEADER_802_11) Elem->Msg;
if (pHeader->FC.SubType & 0x08)
Offset += 2;
pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?