wpa.c
来自「台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 」· C语言 代码 · 共 1,350 行 · 第 1/4 页
C
1,350 行
========================================================================
*/
VOID WpaGroupMsg1Action(
IN PRT2570ADAPTER pAdapter,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR *OutBuffer = NULL;
HEADER_802_11 Header_802_11;
NDIS_STATUS NStatus;
UCHAR AckRate = RATE_2;
USHORT AckDuration = 0;
ULONG FrameLen = 0;
UCHAR EAPHEAD[8] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,0x88,0x8e};
EAPOL_PACKET Packet;
PEAPOL_PACKET pGroup;
UCHAR Mic[16], OldMic[16];
UCHAR GTK[32], Key[32];
NDIS_802_11_KEY GroupKey;
UCHAR MSG[MAX_LEN_OF_MLME_BUFFER];
if(NdisEqualMemory(&Elem->Msg[LENGTH_802_11 + 8], EAPHEAD, LENGTH_802_1_H))
{
DBGPRINT(RT_DEBUG_ERROR, "WpaGroupMsg1Action ----->MsgLen=%d\n",Elem->MsgLen);
NdisMoveMemory(MSG, Elem->Msg, LENGTH_802_11);
NdisMoveMemory(&MSG[LENGTH_802_11], &Elem->Msg[LENGTH_802_11+8], (Elem->MsgLen ));
}
else
{
DBGPRINT(RT_DEBUG_ERROR, "WpaGroupMsg1Action ----->2\n");
NdisMoveMemory(MSG, Elem->Msg, Elem->MsgLen);
}
// Process Group message 1 frame.
pGroup = (PEAPOL_PACKET) &MSG[LENGTH_802_11 + LENGTH_802_1_H];
// pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + 8];//red
// 1. Verify Replay counter
// Check Replay Counter, it has to be larger than last one. No need to be exact one larger
if (RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAdapter->PortCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
{
DBGPRINT(RT_DEBUG_ERROR,"Different Replay Counter in Group 2 Handshake\n");
return;
}
// Update new replay counter
NdisMoveMemory(pAdapter->PortCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
// 2. Verify MIC is valid
// Save the MIC and replace with zero
NdisZeroMemory(OldMic, LEN_KEY_DESC_MIC);
NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
{
// AES
UCHAR digest[80];
HMAC_SHA1((PUCHAR) pGroup, pGroup->Len[1] + 4, pAdapter->PortCfg.PTK, LEN_EAP_MICK, digest);
NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
}
else
{
hmac_md5(pAdapter->PortCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, 131, Mic);
}
if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
{
DBGPRINT(RT_DEBUG_ERROR, " MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n");
return;
}
else
DBGPRINT(RT_DEBUG_TEMP, " MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n");
// 3. Decrypt GTK from Key Data
if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
{
if (pGroup->KeyDesc.KeyInfo.KeyDescVer != 2)
return;
// Decrypt AES GTK
AES_GTK_KEY_UNWRAP(&pAdapter->PortCfg.PTK[16], GTK, pGroup->KeyDesc.KeyData);
}
else // TKIP
{
INT i;
if (pGroup->KeyDesc.KeyInfo.KeyDescVer != 1)
return;
// Decrypt TKIP GTK
// Construct 32 bytes RC4 Key
NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
NdisMoveMemory(&Key[16], &pAdapter->PortCfg.PTK[16], 16);
ARCFOUR_INIT(&pAdapter->PrivateInfo.WEPCONTEXT, Key, 32);
//discard first 256 bytes
for (i = 0; i < 256; i++)
ARCFOUR_BYTE(&pAdapter->PrivateInfo.WEPCONTEXT);
// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
ARCFOUR_DECRYPT(&pAdapter->PrivateInfo.WEPCONTEXT, GTK, pGroup->KeyDesc.KeyData, 32);
}
// 4. Construct Group Message 2
pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
WpaMacHeaderInit(pAdapter, &Header_802_11, 1, &pAdapter->PortCfg.Bssid);
// ACK size is 14 include CRC, and its rate is based on real time information
AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
AckDuration = RTUSBCalcDuration(pAdapter, AckRate, 14);
Header_802_11.Controlhead.Duration = pAdapter->PortCfg.Dsifs + AckDuration;
// Zero Group message 1 body
NdisZeroMemory(&Packet, sizeof(Packet));
Packet.Version = EAPOL_VER;
Packet.Type = EAPOLKey;
Packet.Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
//
// Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
//
Packet.KeyDesc.Type = RSN_KEY_DESC;
// Key descriptor version and appropriate RSN IE
Packet.KeyDesc.KeyInfo.KeyDescVer = pGroup->KeyDesc.KeyInfo.KeyDescVer;
// Key Type Group key
Packet.KeyDesc.KeyInfo.KeyType = 0;
// KeyMic field presented
Packet.KeyDesc.KeyInfo.KeyMic = 1;
// Secure bit is 1
Packet.KeyDesc.KeyInfo.Secure = 1;
// Key Replay count
NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
// Out buffer for transmitting group message 2
NStatus = MlmeAllocateMemory(pAdapter, (PVOID)&OutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
return;
// Prepare EAPOL frame for MIC calculation
// Be careful, only EAPOL frame is counted for MIC calculation
MakeOutgoingFrame(OutBuffer, &FrameLen,
Packet.Len[1] + 4 , &Packet,
END_OF_ARGS);
// Prepare and Fill MIC value
NdisZeroMemory(Mic, sizeof(Mic));
if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
{
// AES
UCHAR digest[80];
HMAC_SHA1(OutBuffer, FrameLen, pAdapter->PortCfg.PTK, LEN_EAP_MICK, digest);
NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
}
else
{
hmac_md5(pAdapter->PortCfg.PTK, LEN_EAP_MICK, OutBuffer, FrameLen, Mic);
}
NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
FrameLen = 0;
MakeOutgoingFrame(OutBuffer, &FrameLen, sizeof(MACHDR), &Header_802_11,
// 8,pTempIvEiv,
sizeof(EAPHEAD), EAPHEAD,
Packet.Len[1] + 4, &Packet,
END_OF_ARGS);
// 5. Copy frame to Tx ring and prepare for encryption
WpaHardEncrypt(pAdapter, OutBuffer, FrameLen);
// 6 Free allocated memory
MlmeFreeMemory(pAdapter, OutBuffer);
// 6. Update GTK
NdisZeroMemory(&GroupKey, sizeof(GroupKey));
GroupKey.Length = sizeof(GroupKey);
GroupKey.KeyIndex = 0x80000000 | pGroup->KeyDesc.KeyInfo.KeyIndex;
GroupKey.KeyLength = 16;
NdisMoveMemory(GroupKey.BSSID, pAdapter->PortCfg.Bssid.Octet, 6);
NdisMoveMemory(GroupKey.KeyMaterial, GTK, 32);
// Call Add peer key function
RTMPWPAAddKeyProc(pAdapter, &GroupKey);
DBGPRINT(RT_DEBUG_TRACE, "WpaGroupMsg1Action <-----\n");
}
/*
========================================================================
Routine Description:
Init WPA MAC header
Arguments:
pAdapter Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID WpaMacHeaderInit(
IN PRT2570ADAPTER pAd,
IN OUT PHEADER_802_11 Hdr,
IN UCHAR wep,
IN PMACADDR pAddr1)
{
NdisZeroMemory(Hdr, sizeof(HEADER_802_11));
Hdr->Controlhead.Frame.Type = BTYPE_DATA;
Hdr->Controlhead.Frame.ToDs = 1;
if (wep == 1)
Hdr->Controlhead.Frame.Wep = 1;
// Addr1: DA, Addr2: BSSID, Addr3: SA
COPY_MAC_ADDR(&Hdr->Controlhead.Addr1, pAddr1);
COPY_MAC_ADDR(&Hdr->Controlhead.Addr2, &pAd->CurrentAddress);
COPY_MAC_ADDR(&Hdr->Addr3, &pAd->PortCfg.Bssid);
Hdr->Sequence = pAd->Sequence;
}
/*
========================================================================
Routine Description:
Copy frame from waiting queue into relative ring buffer and set
appropriate ASIC register to kick hardware encryption before really
sent out to air.
Arguments:
pAdapter Pointer to our adapter
PNDIS_PACKET Pointer to outgoing Ndis frame
NumberOfFrag Number of fragment required
Return Value:
None
Note:
========================================================================
*/
VOID WpaHardEncrypt(
IN PRT2570ADAPTER pAdapter,
IN PUCHAR pPacket,
IN ULONG Len)
{
CHAR *OutBuffer = NULL;
UCHAR FrameGap;
PUCHAR pDest;
PUCHAR pSrc;
ULONG Iv16;
ULONG Iv32;
PWPA_KEY pWpaKey;
NDIS_STATUS NStatus;
NStatus = MlmeAllocateMemory(pAdapter, (PVOID)&OutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, "WPA - WpaHardEncrypt allocate memory failed\n");
pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
MlmeCntlConfirm(pAdapter, MT2_DISASSOC_CONF, MLME_FAIL_NO_RESOURCE);
return;
}
FrameGap = IFS_BACKOFF; // Default frame gap mode
pDest = (PUCHAR)OutBuffer;
pSrc = pPacket; // Point to start of MSDU
// outgoing frame always wakeup PHY to prevent frame lost and
// turn off PSM bit to improve performance
if (pAdapter->PortCfg.Psm == PWR_SAVE)
{
MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
}
AsicForceWakeup(pAdapter);
pWpaKey = (PWPA_KEY) &pAdapter->PortCfg.PairwiseKey[0];
pWpaKey->Type = PAIRWISE_KEY;
if (pWpaKey->KeyLen == 0)
{
// No pairwise key, this should not happen
//NdisReleaseSpinLock(&pAdapter->TxRingLock);
DBGPRINT(RT_DEBUG_ERROR,"no pairwise key\n");
return;
}
if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)
{
INT i = 0;
// Start CALCULATE MIC Value
RTMPInitMICEngine(
pAdapter,
pWpaKey->Key,
pSrc + 4,
pSrc + 10,
pWpaKey->TxMic);
NdisMoveMemory(pDest, pSrc, LENGTH_802_11);
pDest += LENGTH_802_11;
pSrc += LENGTH_802_11;
RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pSrc, (Len - LENGTH_802_11));
RTMPTkipGetMIC(&pAdapter->PrivateInfo.Tx);
//pAdapter->PrivateInfo.Tx.MIC[3]++;
// Prepare IV, EIV, IV offset, Key for hardware encryption
RTMPInitTkipEngine(
pAdapter,
pWpaKey->Key,
0,
pAdapter->CurrentAddress,
pWpaKey->TxMic,
pWpaKey->TxTsc,
1,
&Iv16,
&Iv32,
pDest);
// Increase TxTsc value for next transmission
while (++pWpaKey->TxTsc[i] == 0x0)
{
i++;
if (i == 6)
break;
}
if (i == 6)
{
// TODO: TSC has done one full cycle, do re-keying stuff follow specs
// Should send a special event microsoft defined to request re-key
}
pDest += 8;
RTMPTkipEncryptData(pAdapter, pSrc, pDest, (Len-LENGTH_802_11));
pDest += (Len-LENGTH_802_11);
//printk("-4\n");
RTMPTkipEncryptData(pAdapter, pAdapter->PrivateInfo.Tx.MIC, pDest, 8);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?