📄 wpa.c
字号:
DBGPRINT_RAW(RT_DEBUG_INFO, "PTK = ");
for (i = 0; i < 64; i++)
DBGPRINT_RAW(RT_DEBUG_INFO, "%2x-", pAd->PortCfg.PTK[i]);
DBGPRINT_RAW(RT_DEBUG_INFO, "\n FrameLen = %d\n", FrameLen);
hmac_md5(pAd->PortCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
}
NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
FrameLen = 0;
MakeOutgoingFrame(pOutBuffer, &FrameLen,
LENGTH_802_3, &Header802_3,
// sizeof(EAPHEAD), EAPHEAD,
Packet.Len[1] + 4, &Packet,
END_OF_ARGS);
// 5. Copy frame to Tx ring and prepare for encryption
RTMPToWirelessSta(pAd, pOutBuffer, FrameLen);
// Free allocated memory
MlmeFreeMemory(pAd, pOutBuffer);
// 6. Update GTK
NdisZeroMemory(pGroupKey, sizeof(NDIS_802_11_KEY) + LEN_EAP_KEY);
pGroupKey->Length = sizeof(NDIS_802_11_KEY) + LEN_EAP_KEY;
pGroupKey->KeyIndex = 0x20000000 | pGroup->KeyDesc.KeyInfo.KeyIndex;
pGroupKey->KeyLength = pGroup->KeyDesc.KeyLength[0] * 256 + pGroup->KeyDesc.KeyLength[1];
COPY_MAC_ADDR(pGroupKey->BSSID, pAd->PortCfg.Bssid);
NdisMoveMemory(pGroupKey->KeyMaterial, GTK, LEN_EAP_KEY);
// Call Add peer key function
RTMPWPAAddKeyProc(pAd, pGroupKey);
kfree(pGroupKey);
kfree(mpool);
DBGPRINT(RT_DEBUG_TRACE, "WpaGroupMsg1Action <-----\n");
}
/*
========================================================================
Routine Description:
Init WPA MAC header
Arguments:
pAd Pointer to our adapter
Return Value:
None
Note:
========================================================================
*/
VOID WpaMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR wep,
IN PUCHAR pAddr1)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_DATA;
pHdr80211->FC.ToDs = 1;
if (wep == 1)
pHdr80211->FC.Wep = 1;
// Addr1: DA, Addr2: BSSID, Addr3: SA
COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pHdr80211->Addr3, pAd->PortCfg.Bssid);
pHdr80211->Sequence = pAd->Sequence;
}
/*
========================================================================
Routine Description:
SHA1 function
Arguments:
Return Value:
Note:
========================================================================
*/
VOID HMAC_SHA1(
IN UCHAR *text,
IN UINT text_len,
IN UCHAR *key,
IN UINT key_len,
IN UCHAR *digest)
{
SHA_CTX context;
UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */
UCHAR k_opad[65]; /* outer padding - key XORd with opad */
INT i;
// if key is longer than 64 bytes reset it to key=SHA1(key)
if (key_len > 64)
{
SHA_CTX tctx;
SHAInit(&tctx);
SHAUpdate(&tctx, key, key_len);
SHAFinal(&tctx, key);
key_len = 20;
}
NdisZeroMemory(k_ipad, sizeof(k_ipad));
NdisZeroMemory(k_opad, sizeof(k_opad));
NdisMoveMemory(k_ipad, key, key_len);
NdisMoveMemory(k_opad, key, key_len);
// XOR key with ipad and opad values
for (i = 0; i < 64; i++)
{
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
// perform inner SHA1
SHAInit(&context); /* init context for 1st pass */
SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
SHAUpdate(&context, text, text_len); /* then text of datagram */
SHAFinal(&context, digest); /* finish up 1st pass */
//perform outer SHA1
SHAInit(&context); /* init context for 2nd pass */
SHAUpdate(&context, k_opad, 64); /* start with outer pad */
SHAUpdate(&context, digest, 20); /* then results of 1st hash */
SHAFinal(&context, digest); /* finish up 2nd pass */
}
/*
========================================================================
Routine Description:
Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
GTK is encaptulated in KDE format at p.83 802.11i D10
Arguments:
Return Value:
Note:
802.11i D10
========================================================================
*/
VOID ParseKeyData(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKeyData,
IN UCHAR KeyDataLen)
{
PKDE_ENCAP pKDE = NULL;
PNDIS_802_11_KEY pGroupKey = NULL;
PUCHAR pMyKeyData = pKeyData;
UCHAR KeyDataLength = KeyDataLen;
UCHAR GTKLEN;
INT i;
if (!NdisEqualMemory(pKeyData, pAd->PortCfg.RSN_IE, pAd->PortCfg.RSN_IELen))
{
DBGPRINT(RT_DEBUG_ERROR, " RSN IE mismatched !!!!!!!!!! \n");
}
else
DBGPRINT(RT_DEBUG_TRACE, " RSN IE matched !!!!!!!!!! \n");
DBGPRINT(RT_DEBUG_ERROR, "KeyDataLen = %d \n", KeyDataLen);
/*
====================================================================
======================================================================
*/
if ((*pKeyData == WPARSNIE) && (*(pKeyData+1) != 0) && (KeyDataLength >= (2 + *(pKeyData+1))))
{
pMyKeyData = pKeyData + *(pKeyData+1) + 2;
KeyDataLength -= (2 + *(pKeyData+1));
DBGPRINT_RAW(RT_DEBUG_TRACE,"WPA RSN IE length %d contained in Msg3 = \n", (2 + *(pKeyData+1)));
}
if ((*pMyKeyData == WPA2RSNIE) && (*(pMyKeyData+1) != 0) && (KeyDataLength >= (2 + *(pMyKeyData+1))))
{
pMyKeyData += (*(pMyKeyData+1) + 2);
KeyDataLength -= (2 + *(pMyKeyData+1));
DBGPRINT_RAW(RT_DEBUG_TRACE,"WPA2 RSN IE length %d contained in Msg3 = \n", (2 + *(pMyKeyData+1)));
}
DBGPRINT_RAW(RT_DEBUG_TRACE,"KeyDataLength %d \n", KeyDataLength);
if ((KeyDataLength >= 8) && (KeyDataLength <= sizeof(KDE_ENCAP)))
{
pKDE = (PKDE_ENCAP) pMyKeyData;
DBGPRINT_RAW(RT_DEBUG_TRACE,"pKDE = \n");
DBGPRINT_RAW(RT_DEBUG_TRACE,"pKDE->Type %x:", pKDE->Type);
DBGPRINT_RAW(RT_DEBUG_TRACE,"pKDE->Len 0x%x:", pKDE->Len);
DBGPRINT_RAW(RT_DEBUG_TRACE,"pKDE->OUI %x %x %x :", pKDE->OUI[0],pKDE->OUI[1],pKDE->OUI[2] );
DBGPRINT_RAW(RT_DEBUG_TRACE,"\n");
}
if (pKDE->GTKEncap.Kid == 0)
{
DBGPRINT_RAW(RT_DEBUG_ERROR,"GTK Key index zero , error\n");
return;
}
GTKLEN = pKDE->Len -6;
DBGPRINT_RAW(RT_DEBUG_TRACE,"GTK Key[%d] len=%d ", pKDE->GTKEncap.Kid, GTKLEN);
for (i = 0; i < GTKLEN; i++)
{
DBGPRINT_RAW(RT_DEBUG_TRACE,"%02x:", pKDE->GTKEncap.GTK[i]);
}
DBGPRINT_RAW(RT_DEBUG_TRACE,"\n");
// Update GTK
pGroupKey = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); // allocate memory
if (pGroupKey == NULL)
return;
NdisZeroMemory(pGroupKey, sizeof(NDIS_802_11_KEY) + LEN_EAP_KEY);
pGroupKey->Length = sizeof(NDIS_802_11_KEY) + LEN_EAP_KEY;
pGroupKey->KeyIndex = 0x20000000 | pKDE->GTKEncap.Kid;
pGroupKey->KeyLength = GTKLEN;
COPY_MAC_ADDR(pGroupKey->BSSID, pAd->PortCfg.Bssid);
NdisMoveMemory(pGroupKey->KeyMaterial, pKDE->GTKEncap.GTK, 32);
// Call Add peer key function
RTMPWPAAddKeyProc(pAd, pGroupKey);
kfree(pGroupKey);
}
VOID WPAMake8023Hdr(
IN PRTMP_ADAPTER pAd,
IN PCHAR pDAddr,
IN OUT PCHAR pHdr)
{
// Addr1: DA, Addr2: BSSID, Addr3: SA
NdisMoveMemory(pHdr, pDAddr, MAC_ADDR_LEN);
NdisMoveMemory(&pHdr[MAC_ADDR_LEN], pAd->CurrentAddress, MAC_ADDR_LEN);
pHdr[2*MAC_ADDR_LEN] = 0x88;
pHdr[2*MAC_ADDR_LEN+1] = 0x8e;
}
/*
========================================================================
Routine Description:
PRF function
Arguments:
Return Value:
Note:
802.1i Annex F.9
========================================================================
*/
VOID PRF(
IN UCHAR *key,
IN INT key_len,
IN UCHAR *prefix,
IN INT prefix_len,
IN UCHAR *data,
IN INT data_len,
OUT UCHAR *output,
IN INT len)
{
INT i;
UCHAR input[1024];
INT currentindex = 0;
INT total_len;
NdisMoveMemory(input, prefix, prefix_len);
input[prefix_len] = 0;
NdisMoveMemory(&input[prefix_len + 1], data, data_len);
total_len = prefix_len + 1 + data_len;
input[total_len] = 0;
total_len++;
for (i = 0; i < (len + 19) / 20; i++)
{
HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
currentindex += 20;
input[total_len - 1]++;
}
}
/*
========================================================================
Routine Description:
Count TPTK from PMK
Arguments:
Return Value:
Output Store the TPTK
Note:
========================================================================
*/
VOID WpaCountPTK(
IN UCHAR *PMK,
IN UCHAR *ANonce,
IN UCHAR *AA,
IN UCHAR *SNonce,
IN UCHAR *SA,
OUT UCHAR *output,
IN UINT len)
{
UCHAR concatenation[76];
UINT CurrPos = 0;
UCHAR temp[32];
UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
NdisZeroMemory(temp, sizeof(temp));
// Get smaller address
if (RTMPCompareMemory(SA, AA, 6) == 1)
NdisMoveMemory(concatenation, AA, 6);
else
NdisMoveMemory(concatenation, SA, 6);
CurrPos += 6;
// Get larger address
if (RTMPCompareMemory(SA, AA, 6) == 1)
NdisMoveMemory(&concatenation[CurrPos], SA, 6);
else
NdisMoveMemory(&concatenation[CurrPos], AA, 6);
CurrPos += 6;
// Get smaller address
if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
else
NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
CurrPos += 32;
// Get larger address
if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
else
NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
CurrPos += 32;
PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
}
/*
========================================================================
Routine Description:
Misc function to Generate random number
Arguments:
Return Value:
Note:
802.1i Annex F.9
========================================================================
*/
VOID GenRandom(
IN PRTMP_ADAPTER pAd,
OUT UCHAR *random)
{
INT i, curr;
UCHAR local[80], KeyCounter[32];
UCHAR result[80];
ULONG CurrentTime;
UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
NdisZeroMemory(result, 80);
NdisZeroMemory(local, 80);
NdisZeroMemory(KeyCounter, 32);
COPY_MAC_ADDR(local, pAd->CurrentAddress);
for (i = 0; i < 32; i++)
{
curr = MAC_ADDR_LEN;
CurrentTime = jiffies;
COPY_MAC_ADDR(local, pAd->CurrentAddress);
curr += MAC_ADDR_LEN;
NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
curr += sizeof(CurrentTime);
NdisMoveMemory(&local[curr], r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -