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

📄 cmm_wpa.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 3 页
字号:
			    	}		else    	{			DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));	        return FALSE;    	}		DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));		// skip it		pMyKeyData += 8;		KeyDataLength -= 8;			}	else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)	{		DefaultIdx = GroupKeyIndex;		DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));	}			// Sanity check - shared key index must be 1 ~ 3	if (DefaultIdx < 1 || DefaultIdx > 3)    {     	DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));        return FALSE;    } #ifdef CONFIG_STA_SUPPORT	// Todo#endif // CONFIG_STA_SUPPORT //	return TRUE; }/*	========================================================================		Routine Description:		Construct EAPoL message for WPA handshaking 		Its format is below,				+--------------------+		| Protocol Version	 |  1 octet		+--------------------+		| Protocol Type		 |	1 octet			+--------------------+		| Body Length		 |  2 octets		+--------------------+		| Descriptor Type	 |	1 octet		+--------------------+		| Key Information    |	2 octets		+--------------------+		| Key Length	     |  1 octet		+--------------------+		| Key Repaly Counter |	8 octets		+--------------------+		| Key Nonce		     |  32 octets		+--------------------+		| Key IV			 |  16 octets		+--------------------+		| Key RSC			 |  8 octets		+--------------------+		| Key ID or Reserved |	8 octets		+--------------------+		| Key MIC			 |	8 octets		+--------------------+		| Key Data Length	 |	2 octets		+--------------------+		| Key Data			 |	n octets		+--------------------+			Arguments:		pAd			Pointer	to our adapter					Return Value:		None			Note:			========================================================================*/VOID	ConstructEapolMsg(	IN 	PRTMP_ADAPTER    	pAd,    IN 	UCHAR				AuthMode,    IN 	UCHAR				WepStatus,    IN 	UCHAR				GroupKeyWepStatus,    IN 	UCHAR				MsgType,      IN	UCHAR				DefaultKeyIdx,    IN 	UCHAR				*ReplayCounter,	IN 	UCHAR				*KeyNonce,	IN	UCHAR				*TxRSC,	IN	UCHAR				*PTK,	IN	UCHAR				*GTK,	IN	UCHAR				*RSNIE,	IN	UCHAR				RSNIE_Len,    OUT PEAPOL_PACKET       pMsg){	BOOLEAN	bWPA2 = FALSE;	// Choose WPA2 or not	if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))		bWPA2 = TRUE;		    // Init Packet and Fill header        pMsg->ProVer = EAPOL_VER;    pMsg->ProType = EAPOLKey;	// Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field	pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;  	// Fill in EAPoL descriptor	if (bWPA2)		pMsg->KeyDesc.Type = WPA2_KEY_DESC;	else		pMsg->KeyDesc.Type = WPA1_KEY_DESC;				// Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 	// When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.	pMsg->KeyDesc.KeyInfo.KeyDescVer =         	(((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));	// Specify Key Type as Group(0) or Pairwise(1)	if (MsgType >= EAPOL_GROUP_MSG_1)		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;	else		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;	// Specify Key Index, only group_msg1_WPA1	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;		if (MsgType == EAPOL_PAIR_MSG_3)		pMsg->KeyDesc.KeyInfo.Install = 1;		if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))		pMsg->KeyDesc.KeyInfo.KeyAck = 1;	if (MsgType != EAPOL_PAIR_MSG_1)			pMsg->KeyDesc.KeyInfo.KeyMic = 1; 	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))    {                               	pMsg->KeyDesc.KeyInfo.Secure = 1;                       }	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))    {                               	        pMsg->KeyDesc.KeyInfo.EKD_DL = 1;                }#ifdef BIG_ENDIAN	// key Information element has done. 	// Swap byte-order for big-endian platforn	*(USHORT *)(&pMsg->KeyDesc.KeyInfo) = SWAP16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));#endif	// Fill in Key Length	{		if (MsgType >= EAPOL_GROUP_MSG_1)		{			// the length of group key cipher			pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);		}		else		{			// the length of pairwise key cipher			pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);					}					}				 	// Fill in replay counter        		    NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);	// Fill Key Nonce field		  	// ANonce : pairwise_msg1 & pairwise_msg3	// SNonce : pairwise_msg2	// GNonce : group_msg1_wpa1		if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))    	NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);	// Fill key IV - WPA2 as 0, WPA1 as random	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))	{				// Suggest IV be random number plus some number,		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);		        pMsg->KeyDesc.KeyIv[15] += 2;			}	    // Fill Key RSC field            // It contains the RSC for the GTK being installed.	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))	{		        NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);	}	// Clear Key MIC field for MIC calculation later       NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);		ConstructEapolKeyData(pAd, 						  AuthMode,						  WepStatus,						  GroupKeyWepStatus, 						  MsgType, 						  DefaultKeyIdx, 						  bWPA2, 						  PTK,						  GTK,						  RSNIE,						  RSNIE_Len,						  pMsg); 	// Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.	if (MsgType != EAPOL_PAIR_MSG_1)	{		CalculateMIC(pAd, WepStatus, PTK, pMsg);	}	DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));	DBGPRINT(RT_DEBUG_TRACE, ("	     Body length = %d \n", pMsg->Body_Len[1]));	DBGPRINT(RT_DEBUG_TRACE, ("	     Key length  = %d \n", pMsg->KeyDesc.KeyLength[1]));}/*	========================================================================		Routine Description:		Construct the Key Data field of EAPoL message 	Arguments:		pAd			Pointer	to our adapter		Elem		Message body			Return Value:		None			Note:			========================================================================*/VOID	ConstructEapolKeyData(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR			AuthMode,	IN	UCHAR			WepStatus,	IN	UCHAR			GroupKeyWepStatus,	IN 	UCHAR			MsgType,	IN	UCHAR			DefaultKeyIdx,	IN	BOOLEAN			bWPA2Capable,	IN	UCHAR			*PTK,	IN	UCHAR			*GTK,	IN	UCHAR			*RSNIE,	IN	UCHAR			RSNIE_LEN,	OUT PEAPOL_PACKET   pMsg){	UCHAR		*mpool, *Key_Data, *Rc4GTK;  	UCHAR       ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];   	UCHAR		data_offset;	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)		return; 	// allocate memory pool	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);    if (mpool == NULL)		return;        	/* Rc4GTK Len = 512 */	Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);	/* Key_Data Len = 512 */	Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);	NdisZeroMemory(Key_Data, 512);	pMsg->KeyDesc.KeyDataLen[1] = 0;	data_offset = 0;		// Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3			if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))	{		if (bWPA2Capable)						Key_Data[data_offset + 0] = IE_WPA2;				else						 							Key_Data[data_offset + 0] = IE_WPA;            					        Key_Data[data_offset + 1] = RSNIE_LEN;		NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);		data_offset += (2 + RSNIE_LEN);	}	// Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2	if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))	{		// Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h        Key_Data[data_offset + 0] = 0xDD;		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)		{			Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)					}		else		{			Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)					}		        Key_Data[data_offset + 2] = 0x00;        Key_Data[data_offset + 3] = 0x0F;        Key_Data[data_offset + 4] = 0xAC;        Key_Data[data_offset + 5] = 0x01;		// GTK KDE format - 802.11i-2004  Figure-43x        Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);        Key_Data[data_offset + 7] = 0x00;	// Reserved Byte						data_offset += 8;	}	// Encapsulate GTK and encrypt the key-data field with KEK.	// Only for pairwise_msg3_WPA2 and group_msg1	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))	{				// Fill in GTK 		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)		{						NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);			data_offset += LEN_AES_KEY;		}		else		{						NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);			data_offset += TKIP_GTK_LENGTH;		}		// Still dont know why, but if not append will occur "GTK not include in MSG3"		// Patch for compatibility between zero config and funk		if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)		{			if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)			{				Key_Data[data_offset + 0] = 0xDD;				Key_Data[data_offset + 1] = 0;				data_offset += 2;			}			else			{				Key_Data[data_offset + 0] = 0xDD;				Key_Data[data_offset + 1] = 0;				Key_Data[data_offset + 2] = 0;				Key_Data[data_offset + 3] = 0;				Key_Data[data_offset + 4] = 0;				Key_Data[data_offset + 5] = 0;				data_offset += 6;			}		}		// Encrypt the data material in key data field		if (WepStatus == Ndis802_11Encryption3Enabled)		{			AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);            // AES wrap function will grow 8 bytes in length            data_offset += 8;            						}		else		{			// PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)			// put TxTsc in Key RSC field			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.			// ekey is the contanetion of IV-field, and PTK[16]->PTK[31]			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));  //INIT SBOX, KEYLEN+3(IV)			pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);  		}		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);	}	else	{		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);	}	// set key data length field and total length	pMsg->KeyDesc.KeyDataLen[1] = data_offset;		    pMsg->Body_Len[1] += data_offset;	os_free_mem(pAd, mpool);}VOID	CalculateMIC(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR			PeerWepStatus,	IN	UCHAR			*PTK,	OUT PEAPOL_PACKET   pMsg){    UCHAR   *OutBuffer;	ULONG	FrameLen = 0;	UCHAR	mic[LEN_KEY_DESC_MIC];	UCHAR	digest[80];	// allocate memory for MIC calculation	os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);    if (OutBuffer == NULL)    {		DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));		return;    }			// make a frame for calculating MIC.    MakeOutgoingFrame(OutBuffer,            	&FrameLen,                      pMsg->Body_Len[1] + 4,  	pMsg,                      END_OF_ARGS);	NdisZeroMemory(mic, sizeof(mic));				// Calculate MIC    if (PeerWepStatus == Ndis802_11Encryption3Enabled) 	{		HMAC_SHA1(OutBuffer,  FrameLen, PTK, LEN_EAP_MICK, digest);		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);	}	else	{		hmac_md5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, mic);	}	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);	os_free_mem(pAd, OutBuffer);}

⌨️ 快捷键说明

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