wpa.c
来自「台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 」· C语言 代码 · 共 1,350 行 · 第 1/4 页
C
1,350 行
pDest += 8;
Len += 8;
RTMPSetICV(pAdapter, pDest);
Len += 12;
MiniportMMRequest(pAdapter, OutBuffer, Len);
}
else if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)
{
#if 0
INT i;
PUCHAR pTmp;
i = 0;
pTmp = (PUCHAR) &Iv16;
*pTmp = pWpaKey->TxTsc[0];
*(pTmp + 1) = pWpaKey->TxTsc[1];
*(pTmp + 2) = 0;
*(pTmp + 3) = 0x20;
Iv32 = *(PULONG)(&pWpaKey->TxTsc[2]);
// Increase TxTsc value for next transmission
while (++pWpaKey->TxTsc[i] == 0x0)
{
i++;
if (i == 6)
break;
}
// Copy IV
NdisMoveMemory(&pTxD->Iv, &Iv16, 4);
// Copy EIV
NdisMoveMemory(&pTxD->Eiv, &Iv32, 4);
// Set IV offset
pTxD->IvOffset = LENGTH_802_11;
// Copy TKey
//red,NdisMoveMemory(pTxD->Key, pWpaKey->Key, 16);
// Set Cipher suite
//red,CipherAlg = CIPHER_AES;
//red
pTempDest += LENGTH_802_11;
NdisMoveMemory(pTempDest, &Iv16, 4);
pTempDest += 4;
NdisMoveMemory(pTempDest, &Iv32, 4);
pTempDest += 4;
// IV + EIV + HW MIC
//red,Asic's suggestionLen += 16;
PLCPLength = Len + 12;//12 is MIC + crc32
#endif
}
}
/*
========================================================================
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:
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 PRT2570ADAPTER 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);
NdisMoveMemory(local, pAd->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
for (i = 0; i < 32; i++)
{
curr = ETH_LENGTH_OF_ADDRESS;
CurrentTime = jiffies;
NdisMoveMemory(local, pAd->CurrentAddress, ETH_LENGTH_OF_ADDRESS);
curr += ETH_LENGTH_OF_ADDRESS;
NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
curr += sizeof(CurrentTime);
NdisMoveMemory(&local[curr], result, 32);
curr += 32;
NdisMoveMemory(&local[curr], &i, 2);
curr += 2;
PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
}
NdisMoveMemory(random, result, 32);
}
/*
========================================================================
Routine Description:
Misc function to decrypt AES body
Arguments:
Return Value:
Note:
This function references to RFC 3394 for aes key unwrap algorithm.
========================================================================
*/
VOID AES_GTK_KEY_UNWRAP(
IN UCHAR *key,
OUT UCHAR *plaintext,
IN UCHAR *ciphertext)
{
UCHAR A[8], BIN[16], BOUT[16];
UCHAR R1[8],R2[8];
UCHAR xor;
INT num_blocks = 2;
INT j;
aes_context aesctx;
// Initialize
// A = C[0]
NdisMoveMemory(A, ciphertext, 8);
// R1 = C1
NdisMoveMemory(R1, &ciphertext[8], 8);
// R2 = C2
NdisMoveMemory(R2, &ciphertext[16], 8);
aes_set_key(&aesctx, key, 128);
for (j = 5; j >= 0; j--)
{
xor = num_blocks * j + 2;
NdisMoveMemory(BIN, A, 8);
BIN[7] = A[7] ^ xor;
NdisMoveMemory(&BIN[8], R2, 8);
aes_decrypt(&aesctx, BIN, BOUT);
NdisMoveMemory(A, &BOUT[0], 8);
NdisMoveMemory(R2, &BOUT[8], 8);
xor = num_blocks * j + 1;
NdisMoveMemory(BIN, A, 8);
BIN[7] = A[7] ^ xor;
NdisMoveMemory(&BIN[8], R1, 8);
aes_decrypt(&aesctx, BIN, BOUT);
NdisMoveMemory(A, &BOUT[0], 8);
NdisMoveMemory(R1, &BOUT[8], 8);
}
// OUTPUT
NdisMoveMemory(&plaintext[0], R1, 8);
NdisMoveMemory(&plaintext[8], R2, 8);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?