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

📄 wpa.c

📁 无线网卡驱动。大家看看
💻 C
📖 第 1 页 / 共 5 页
字号:
	 //	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,
	IN	UCHAR			KeyIdx,
	IN	BOOLEAN			IsGroupMsg)
{
	PKDE_ENCAP          pKDE = NULL;
	PNDIS_802_11_KEY    pGroupKey = NULL;
	PUCHAR              pMyKeyData=NULL;// = pKeyData;
	UCHAR				*KeyDataBuf, *mpool;
	UCHAR               KeyDataLength = KeyDataLen;
	UCHAR               GTKLEN;
	INT                 i;
	ULONG               Idx;   
	PUCHAR              pVIE=NULL;
	UCHAR               Len;
	PEID_STRUCT         pEid;
	BOOLEAN				bKDE_Key = FALSE;	// Key Data Encapsulation format

	mpool = kmalloc(256, MEM_ALLOC_FLAG);  // allocate memory
	if (mpool == NULL)
		return;

	// KeyDataBuf len = 256.
	KeyDataBuf = (UCHAR *) ROUND_UP(mpool, 4);
	// Init the buffer
	NdisZeroMemory(KeyDataBuf, 256);
	
	if((Idx = BssTableSearch(&pAd->ScanTab, pAd->PortCfg.Bssid, pAd->PortCfg.Channel)) == BSS_NOT_FOUND)
	{
		DBGPRINT(RT_DEBUG_ERROR, "%s, Can't find BSS\n", __FUNCTION__);
		return;
	}
	
	pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
	Len = (UCHAR)pAd->ScanTab.BssEntry[Idx].VarIELen;
	while(Len > 0)
	{
	    pEid = (PEID_STRUCT) pVIE;	
		if (pEid->Eid != IE_RSN)
		{
			pVIE += (pEid->Len + 2);
			Len  -= (pEid->Len + 2);
			continue;
		}

		if (!NdisEqualMemory(pKeyData, pEid->Octet, pEid->Len))
		{
//			DBGPRINT(RT_DEBUG_ERROR, " RSN IE mismatched !!!!!!!!!! \n");
		}
		else
		{
//			DBGPRINT(RT_DEBUG_TRACE, " RSN IE matched !!!!!!!!!! \n");
		}
        
		Len  -= (pEid->Len + 2);    
		break;
	}


/*
====================================================================
======================================================================
*/
	NdisMoveMemory(KeyDataBuf, pKeyData, KeyDataLen);
	pMyKeyData =(PUCHAR) KeyDataBuf;
	if (!IsGroupMsg)
	{
		do{
			if ((*pMyKeyData == WPARSNIE) && (*(pMyKeyData+1) != 0) && (KeyDataLength >= (2 + *(pMyKeyData+1))))      
			{
				if ((*(pMyKeyData+2) == 0x00) && (*(pMyKeyData+3) == 0x0f) && (*(pMyKeyData+4) == 0xac))
					break;
					
				DBGPRINT_RAW(RT_DEBUG_TRACE,"WPA WPA_IE length %d contained in this message \n", (2 + *(pMyKeyData+1)));
				KeyDataLength -= (2 + *(pMyKeyData+1));
				pMyKeyData += *(pMyKeyData+1) + 2;
			}
			if ((*pMyKeyData == WPA2RSNIE) && (*(pMyKeyData+1) != 0) && (KeyDataLength >= (2 + *(pMyKeyData+1))))       
			{
				DBGPRINT_RAW(RT_DEBUG_TRACE,"WPA2 RSN_IE length %d contained in this message \n", (2 + *(pMyKeyData+1)));
				KeyDataLength -= (2 + *(pMyKeyData+1));
				pMyKeyData += (*(pMyKeyData+1) + 2);
			}
			
		} while(KeyDataLength > 0);
	}	
	DBGPRINT_RAW(RT_DEBUG_TRACE,"KeyDataLength %d   \n", KeyDataLength);

	// GTK key Data Encapsulation
	pKDE = (PKDE_ENCAP) pMyKeyData;
	if((KeyDataLength >= 8) && (pKDE->Type == WPARSNIE) && (pKDE->OUI[0] == 0x00) && (pKDE->OUI[1]== 0x0f) && (pKDE->OUI[2]== 0x0ac) && (pKDE->DataType== 0x01))
	{   
		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");                      

		bKDE_Key = TRUE;
	}   
    
	if ((bKDE_Key == TRUE) && (pKDE->GTKEncap.Kid == 0))
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR,"GTK Key index zero , error\n");
		return;
	}


	// 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;
	COPY_MAC_ADDR(pGroupKey->BSSID, pAd->PortCfg.Bssid);

	if (bKDE_Key)	// GTK Key Data Encapsulation
	{
		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");                       

		pGroupKey->KeyIndex  = 0x20000000 | pKDE->GTKEncap.Kid;
		pGroupKey->KeyLength = GTKLEN;

		NdisMoveMemory(pGroupKey->KeyMaterial, pKDE->GTKEncap.GTK, 32);

		// Call Add peer key function
		RTMPWPAAddKeyProc(pAd, pGroupKey);
	}		
	else if (KeyIdx != 0)	// non-KDE Key
	{
		pGroupKey->KeyIndex  = 0x20000000 | KeyIdx;
		pGroupKey->KeyLength = 32;	//KeyDataLen

		NdisMoveMemory(pGroupKey->KeyMaterial, pMyKeyData, LEN_EAP_KEY);

		// Call Add peer key function
		RTMPWPAAddKeyProc(pAd, pGroupKey);
	}

	kfree(pGroupKey);
	kfree(mpool);

}

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;
	INT		currentindex = 0;
	INT		total_len;
	BOOLEAN	bfree = TRUE;

	input = kmalloc(1024, MEM_ALLOC_FLAG);  // allocate memory
    if (input == NULL) 
    {
    	input = prf_input;
		bfree = FALSE;
    }
	
	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]++;
	}	

	if (bfree==TRUE) 
	    kfree(input);
}

/*
	========================================================================
	
	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, *KeyCounter;
	UCHAR	        *result;
	unsigned long	CurrentTime;
	UCHAR	prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
	UCHAR	        *mpool;

	mpool = kmalloc(256, MEM_ALLOC_FLAG);  // allocate memory
	if (mpool == NULL)
        return;

	// local Len = 80.
	local = (UCHAR *) ROUND_UP(mpool, 4);
	// KeyCounter Len = 32.
	KeyCounter = (UCHAR *) ROUND_UP(local + 80, 4);
	// result Len = 80.
	result = (UCHAR *) ROUND_UP(KeyCounter + 32, 4);

	NdisZeroMemory(result, 80);
	Ndi

⌨️ 快捷键说明

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