⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmm_wpa.c

📁 ralink最新rt3070 usb wifi 无线网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	OUT	PUCHAR			pRsnIe,	OUT	UCHAR			*rsn_len){	RSN_CAPABILITIES    *pRSN_Cap;	// it could be ignored in WPA1 mode	if (ElementID == WpaIe)		return;		pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));						 	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);		(*rsn_len) += sizeof(RSN_CAPABILITIES);	// update current RSNIE length}/*	========================================================================	Routine Description:		Build RSN IE context. It is not included element-ID and length.	Arguments:		pAd			-	pointer to our pAdapter context	    	AuthMode	-	indicate the authentication mode    	WepStatus	-	indicate the encryption type		apidx		-	indicate the interface index			Return Value:			Note:			========================================================================*/VOID RTMPMakeRSNIE(    IN  PRTMP_ADAPTER   pAd,    IN  UINT            AuthMode,    IN  UINT            WepStatus,	IN	UCHAR			apidx){	PUCHAR		pRsnIe = NULL;			// primary RSNIE	UCHAR 		*rsnielen_cur_p = 0;	// the length of the primary RSNIE 			UCHAR		*rsnielen_ex_cur_p = 0;	// the length of the secondary RSNIE	  		UCHAR		PrimaryRsnie;				BOOLEAN		bMixCipher = FALSE;	// indicate the pairwise and group cipher are different	UCHAR		p_offset;			WPA_MIX_PAIR_CIPHER		FlexibleCipher = MIX_CIPHER_NOTUSE;	// it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode			rsnielen_cur_p = NULL;	rsnielen_ex_cur_p = NULL;	{#ifdef CONFIG_STA_SUPPORT		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)		{#ifdef WPA_SUPPLICANT_SUPPORT			if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)			{				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;			}					DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));			// Zero RSNIE context 			pAd->StaCfg.RSNIE_Len = 0;			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);			// Pointer to RSNIE 			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;			pRsnIe = pAd->StaCfg.RSN_IE;			bMixCipher = pAd->StaCfg.bMixCipher;								}#endif // CONFIG_STA_SUPPORT //	}	// indicate primary RSNIE as WPA or WPA2	if ((AuthMode == Ndis802_11AuthModeWPA) || 		(AuthMode == Ndis802_11AuthModeWPAPSK) || 		(AuthMode == Ndis802_11AuthModeWPANone) || 		(AuthMode == Ndis802_11AuthModeWPA1WPA2) || 		(AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))		PrimaryRsnie = WpaIe;	else		PrimaryRsnie = Wpa2Ie;	{		// Build the primary RSNIE		// 1. insert cipher suite		RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);			// 2. insert AKM		RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);		// 3. insert capability		RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);	}	// 4. update the RSNIE length	*rsnielen_cur_p = p_offset; 	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));}/*    ==========================================================================    Description:		Check whether the received frame is EAP frame.	Arguments:		pAd				-	pointer to our pAdapter context			pEntry			-	pointer to active entry		pData			-	the received frame		DataByteCount 	-	the received frame's length				FromWhichBSSID	-	indicate the interface index           Return:         TRUE 			-	This frame is EAP frame         FALSE 			-	otherwise    ==========================================================================*/BOOLEAN RTMPCheckWPAframe(    IN PRTMP_ADAPTER    pAd,    IN PMAC_TABLE_ENTRY	pEntry,    IN PUCHAR           pData,    IN ULONG            DataByteCount,	IN UCHAR			FromWhichBSSID){	ULONG	Body_len;	BOOLEAN Cancelled;    if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))        return FALSE;    	// Skip LLC header	    if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||        // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))     {        pData += 6;    }	// Skip 2-bytes EAPoL type     if (NdisEqualMemory(EAPOL, pData, 2))     {        pData += 2;             }    else            return FALSE;    switch (*(pData+1))         {           case EAPPacket:			Body_len = (*(pData+2)<<8) | (*(pData+3));            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));            break;        case EAPOLStart:            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));			if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)            {                	DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));                RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);                pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;                         }				            break;        case EAPOLLogoff:            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));            break;        case EAPOLKey:			Body_len = (*(pData+2)<<8) | (*(pData+3));            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));            break;        case EAPOLASFAlert:            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));            break;        default:            return FALSE;        }       return TRUE;}/*    ==========================================================================    Description:        ENCRYPT AES GTK before sending in EAPOL frame.        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.        This function references to RFC 3394 for aes key wrap algorithm.    Return:    ==========================================================================*/  VOID AES_GTK_KEY_WRAP(     IN UCHAR    *key,    IN UCHAR    *plaintext,    IN UCHAR    p_len,    OUT UCHAR   *ciphertext){    UCHAR       A[8], BIN[16], BOUT[16];    UCHAR       R[512];    INT         num_blocks = p_len/8;   // unit:64bits    INT         i, j;    aes_context aesctx;    UCHAR       xor;    rtmp_aes_set_key(&aesctx, key, 128);    // Init IA    for (i = 0; i < 8; i++)        A[i] = 0xa6;    //Input plaintext    for (i = 0; i < num_blocks; i++)    {        for (j = 0 ; j < 8; j++)            R[8 * (i + 1) + j] = plaintext[8 * i + j];    }    // Key Mix    for (j = 0; j < 6; j++)    {        for(i = 1; i <= num_blocks; i++)        {            //phase 1            NdisMoveMemory(BIN, A, 8);            NdisMoveMemory(&BIN[8], &R[8 * i], 8);            rtmp_aes_encrypt(&aesctx, BIN, BOUT);            NdisMoveMemory(A, &BOUT[0], 8);            xor = num_blocks * j + i;            A[7] = BOUT[7] ^ xor;            NdisMoveMemory(&R[8 * i], &BOUT[8], 8);        }    }    // Output ciphertext    NdisMoveMemory(ciphertext, A, 8);    for (i = 1; i <= num_blocks; i++)    {        for (j = 0 ; j < 8; j++)            ciphertext[8 * i + j] = R[8 * i + j];    }}/*	========================================================================		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    c_len,	IN	UCHAR	*ciphertext)	{	UCHAR       A[8], BIN[16], BOUT[16];	UCHAR       xor;	INT         i, j;	aes_context aesctx;	UCHAR       *R;	INT         num_blocks = c_len/8;	// unit:64bits		os_alloc_mem(NULL, (PUCHAR *)&R, 512);	if (R == NULL)    {        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));        return;    } /* End of if */	// Initialize	NdisMoveMemory(A, ciphertext, 8);	//Input plaintext	for(i = 0; i < (c_len-8); i++)	{		R[ i] = ciphertext[i + 8];	}	rtmp_aes_set_key(&aesctx, key, 128);	for(j = 5; j >= 0; j--)	{		for(i = (num_blocks-1); i > 0; i--)		{			xor = (num_blocks -1 )* j + i;			NdisMoveMemory(BIN, A, 8);			BIN[7] = A[7] ^ xor;			NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);			rtmp_aes_decrypt(&aesctx, BIN, BOUT);			NdisMoveMemory(A, &BOUT[0], 8);			NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);		}	}	// OUTPUT	for(i = 0; i < c_len; i++)	{		plaintext[i] = R[i];	}		os_free_mem(NULL, R);}/*    ==========================================================================    Description:		Report the EAP message type	Arguments:		msg		-	EAPOL_PAIR_MSG_1					EAPOL_PAIR_MSG_2					EAPOL_PAIR_MSG_3					EAPOL_PAIR_MSG_4					EAPOL_GROUP_MSG_1					EAPOL_GROUP_MSG_2											           Return:         message type string    ==========================================================================*/CHAR *GetEapolMsgType(CHAR msg){    if(msg == EAPOL_PAIR_MSG_1)        return "Pairwise Message 1";    else if(msg == EAPOL_PAIR_MSG_2)        return "Pairwise Message 2";	else if(msg == EAPOL_PAIR_MSG_3)        return "Pairwise Message 3";	else if(msg == EAPOL_PAIR_MSG_4)        return "Pairwise Message 4";	else if(msg == EAPOL_GROUP_MSG_1)        return "Group Message 1";	else if(msg == EAPOL_GROUP_MSG_2)        return "Group Message 2";    else    	return "Invalid Message";}/*    ========================================================================        Routine Description:    Check Sanity RSN IE of EAPoL message    Arguments:            Return Value:		    ========================================================================*/BOOLEAN RTMPCheckRSNIE(	IN  PRTMP_ADAPTER   pAd,	IN  PUCHAR          pData,	IN  UCHAR           DataLen,	IN  MAC_TABLE_ENTRY *pEntry,	OUT	UCHAR			*Offset){	PUCHAR              pVIE;	UCHAR               len;	PEID_STRUCT         pEid;	BOOLEAN				result = FALSE;			pVIE = pData;	len	 = DataLen;	*Offset = 0;	while (len > sizeof(RSNIE2))	{		pEid = (PEID_STRUCT) pVIE;			// WPA RSN IE		if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))		{						if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&				(NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&				(pEntry->RSNIE_Len == (pEid->Len + 2)))			{					result = TRUE;							}								*Offset += (pEid->Len + 2);					}		// WPA2 RSN IE		else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))		{			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&				(NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&				(pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)			{					result = TRUE;							}						*Offset += (pEid->Len + 2);		}				else		{						break;		}		pVIE += (pEid->Len + 2);		len  -= (pEid->Len + 2);	}				return result;	}/*    ========================================================================        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              ========================================================================*/BOOLEAN RTMPParseEapolKeyData(	IN  PRTMP_ADAPTER   pAd,	IN  PUCHAR          pKeyData,	IN  UCHAR           KeyDataLen,	IN	UCHAR			GroupKeyIndex,	IN	UCHAR			MsgType,	IN	BOOLEAN			bWPA2,	IN  MAC_TABLE_ENTRY *pEntry){    PKDE_ENCAP          pKDE = NULL;    PUCHAR              pMyKeyData = pKeyData;    UCHAR               KeyDataLength = KeyDataLen;    UCHAR               GTKLEN = 0;	UCHAR				DefaultIdx = 0;	UCHAR				skip_offset;			    	// Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)    {		// Check RSN IE whether it is WPA2/WPA2PSK   				if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))		{			// send wireless event - for RSN IE different			if (pAd->CommonCfg.bWirelessEvent)				RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);         	DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));						hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);			hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);									return FALSE;			    	}    	else		{			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)			{				// skip RSN IE				pMyKeyData += skip_offset;				KeyDataLength -= skip_offset;				DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));			}			else				return TRUE;					}	}	DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));	// Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2	if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))	{						if (KeyDataLength >= 8)	// KDE format exclude GTK length    	{        	pKDE = (PKDE_ENCAP) pMyKeyData;	        						DefaultIdx = pKDE->GTKEncap.Kid;			// Sanity check - KED length			if (KeyDataLength < (pKDE->Len + 2))    		{        		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));        		return FALSE;			    		}			// Get GTK length - refer to IEEE 802.11i-2004 p.82			GTKLEN = pKDE->Len -6;			if (GTKLEN < LEN_AES_KEY)			{				DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));        		return FALSE;			}			    	}		else    	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -