📄 cmm_wpa.c
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* Module Name: wpa.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- Jan Lee 03-07-22 Initial Paul Lin 03-11-28 Modify for supplicant*/#include "rt_config.h"UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};/* ======================================================================== 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; INT currentindex = 0; INT total_len; os_alloc_mem(NULL, (PUCHAR *)&input, 1024); if (input == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n")); return; } /* End of if */ 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]++; } os_free_mem(NULL, input);}/* ======================================================================== Routine Description: Count TPTK from PMK Arguments: Return Value: Output Store the TPTK Note: ========================================================================*/VOID WpaCountPTK( IN PRTMP_ADAPTER pAd, 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'};#ifdef LEAP_SUPPORT UCHAR CCKMPrefix[] = {'F', 'a', 's', 't', '-', 'R', 'o', 'a', 'm', ' ', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', ' ', 'B', 'a', 's', 'e', ' ', 'K', 'e', 'y'};#endif //LEAP_SUPPORT // NdisZeroMemory(temp, sizeof(temp));#ifdef LEAP_SUPPORT if (LEAP_CCKM_ON(pAd)) { NdisMoveMemory(concatenation, AA, 6); CurrPos += 6; NdisMoveMemory(&concatenation[CurrPos], SA, 6); CurrPos += 6; NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); CurrPos += 32; NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); CurrPos += 32; PRF(PMK, 16, CCKMPrefix, 27, concatenation, 76, output, len); } else#endif // LEAP_SUPPORT // { // 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;#ifdef LEAP_SUPPORT if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)) PRF(PMK, 16, Prefix, 22, concatenation, 76, output, len); else#endif // LEAP_SUPPORT // 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, IN UCHAR apidx){ 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); #ifdef CONFIG_STA_SUPPORT COPY_MAC_ADDR(local, pAd->CurrentAddress);#endif // CONFIG_STA_SUPPORT // for (i = 0; i < 32; i++) { curr = MAC_ADDR_LEN; NdisGetSystemUpTime(&CurrentTime);#ifdef CONFIG_STA_SUPPORT COPY_MAC_ADDR(local, pAd->CurrentAddress);#endif // CONFIG_STA_SUPPORT // curr += MAC_ADDR_LEN; 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); }VOID RTMPMakeRSNIE( IN PRTMP_ADAPTER pAd, IN UINT AuthMode, IN UINT WepStatus, IN UCHAR apidx){#ifdef CONFIG_STA_SUPPORT#ifdef WPA_SUPPLICANT_SUPPORT if (pAd->StaCfg.WpaSupplicantUP) { if (AuthMode < Ndis802_11AuthModeWPA) return; } else#endif // WPA_SUPPLICANT_SUPPORT // // Support WPAPSK or WPA2PSK in STA-Infra mode // Support WPANone in STA-Adhoc mode if ((AuthMode != Ndis802_11AuthModeWPAPSK) && (AuthMode != Ndis802_11AuthModeWPA2PSK) && (AuthMode != Ndis802_11AuthModeWPANone)) return; pAd->StaCfg.RSNIE_Len = 0; NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);#endif // CONFIG_STA_SUPPORT // // For WPA1, RSN_IE=221 if ((AuthMode == Ndis802_11AuthModeWPA) || (AuthMode == Ndis802_11AuthModeWPAPSK) || (AuthMode == Ndis802_11AuthModeWPANone) || (AuthMode == Ndis802_11AuthModeWPA1WPA2) || (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { RSNIE *pRsnie; RSNIE_AUTH *pRsnie_auth; RSN_CAPABILITIES *pRSN_Cap; UCHAR Rsnie_size = 0;#ifdef CONFIG_STA_SUPPORT pRsnie = (RSNIE*)pAd->StaCfg.RSN_IE;#endif // CONFIG_STA_SUPPORT // NdisMoveMemory(pRsnie->oui, OUI_WPA_WEP40, 4); pRsnie->version = 1; switch (WepStatus) { case Ndis802_11Encryption2Enabled: NdisMoveMemory(pRsnie->mcast, OUI_WPA_TKIP, 4); pRsnie->ucount = 1; NdisMoveMemory(pRsnie->ucast[0].oui, OUI_WPA_TKIP, 4); Rsnie_size = sizeof(RSNIE); break; case Ndis802_11Encryption3Enabled:#ifdef CONFIG_STA_SUPPORT if (pAd->StaCfg.bMixCipher) NdisMoveMemory(pRsnie->mcast, OUI_WPA_TKIP, 4); else NdisMoveMemory(pRsnie->mcast, OUI_WPA_CCMP, 4);#endif // CONFIG_STA_SUPPORT // pRsnie->ucount = 1; NdisMoveMemory(pRsnie->ucast[0].oui, OUI_WPA_CCMP, 4); Rsnie_size = sizeof(RSNIE); break; } pRsnie_auth = (RSNIE_AUTH*)((PUCHAR)pRsnie + Rsnie_size); switch (AuthMode) { case Ndis802_11AuthModeWPA: case Ndis802_11AuthModeWPA1WPA2: pRsnie_auth->acount = 1; NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_WEP40, 4); break; case Ndis802_11AuthModeWPAPSK: case Ndis802_11AuthModeWPA1PSKWPA2PSK: pRsnie_auth->acount = 1; NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_TKIP, 4); break;#ifdef CONFIG_STA_SUPPORT case Ndis802_11AuthModeWPANone: pRsnie_auth->acount = 1; NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4); break;#endif // CONFIG_STA_SUPPORT // } pRSN_Cap = (RSN_CAPABILITIES*)((PUCHAR)pRsnie_auth + sizeof(RSNIE_AUTH)); #ifdef BIG_ENDIAN pRsnie->version = SWAP16(pRsnie->version); pRsnie->ucount = SWAP16(pRsnie->ucount); pRsnie_auth->acount = SWAP16(pRsnie_auth->acount); pRSN_Cap->word = SWAP16(pRSN_Cap->word);#endif#ifdef CONFIG_STA_SUPPORT pAd->StaCfg.RSNIE_Len = Rsnie_size + sizeof(RSNIE_AUTH) + sizeof(RSN_CAPABILITIES);#endif // CONFIG_STA_SUPPORT // } // For WPA2, RSN_IE=48, if WPA1WPA2/WPAPSKWPA2PSK mix mode, we store RSN_IE in RSN_IE[1] else RSNIE[0] if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK) || (AuthMode == Ndis802_11AuthModeWPA1WPA2) || (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { RSNIE2 *pRsnie2; RSNIE_AUTH *pRsnie_auth2; RSN_CAPABILITIES *pRSN_Cap; UCHAR Rsnie_size = 0;#ifdef CONFIG_STA_SUPPORT pRsnie2 = (RSNIE2*)pAd->StaCfg.RSN_IE;#endif // CONFIG_STA_SUPPORT // pRsnie2->version = 1; switch (WepStatus) { case Ndis802_11Encryption2Enabled: NdisMoveMemory(pRsnie2->mcast, OUI_WPA2_TKIP, 4); pRsnie2->ucount = 1; NdisMoveMemory(pRsnie2->ucast[0].oui, OUI_WPA2_TKIP, 4); Rsnie_size = sizeof(RSNIE2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -