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

📄 rtmp_tkip.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 ***************************************************************************
 * Ralink Tech Inc.
 * 4F, No. 2 Technology 5th Rd.
 * Science-based Industrial Park
 * Hsin-chu, Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2005, Ralink Technology, Inc.
 *
 * All rights reserved. Ralink's source code is an unpublished work and the
 * use of a copyright notice does not imply otherwise. This source code
 * contains confidential trade secret material of Ralink Tech. Any attempt
 * or participation in deciphering, decoding, reverse engineering or in any
 * way altering the source code is stricitly prohibited, unless the prior
 * written consent of Ralink Technology, Inc. is obtained.
 ***************************************************************************

	Module Name:
	rtmp_tkip.c

	Abstract:

	Revision History:
	Who			When			What
	--------	----------		----------------------------------------------
	Paul Wu		02-25-02		Initial
*/

#include	"rt_config.h"

// Rotation functions on 32 bit values 
#define ROL32( A, n ) \
	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) 
#define ROR32( A, n ) ROL32( (A), 32-(n) ) 

UINT Tkip_Sbox_Lower[256] = 
{ 
	0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, 
	0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, 
	0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, 
	0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, 
	0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, 
	0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, 
	0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, 
	0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, 
	0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, 
	0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, 
	0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, 
	0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, 
	0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, 
	0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, 
	0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, 
	0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, 
	0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, 
	0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, 
	0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, 
	0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, 
	0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, 
	0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, 
	0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, 
	0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, 
	0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, 
	0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, 
	0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, 
	0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, 
	0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, 
	0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, 
	0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, 
	0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A 
};

UINT Tkip_Sbox_Upper[256] = 
{ 
	0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, 
	0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, 
	0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, 
	0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, 
	0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, 
	0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, 
	0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, 
	0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, 
	0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, 
	0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, 
	0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, 
	0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, 
	0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, 
	0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, 
	0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, 
	0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, 
	0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, 
	0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, 
	0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, 
	0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, 
	0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, 
	0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, 
	0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, 
	0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, 
	0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, 
	0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, 
	0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, 
	0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, 
	0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, 
	0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, 
	0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, 
	0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C 
}; 

/*****************************/
/******** SBOX Table *********/
/*****************************/

UCHAR SboxTable[256] =
{
	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

VOID xor_32(
	IN  PUCHAR              a,
	IN  PUCHAR              b,
	OUT PUCHAR              out);

VOID xor_128(
	IN  PUCHAR              a,
	IN  PUCHAR              b,
	OUT PUCHAR              out);
	
VOID next_key(
	IN  PUCHAR              key,
	IN  INT                 round);

VOID byte_sub(
	IN  PUCHAR              in,
	OUT PUCHAR              out);

VOID shift_row(
	IN  PUCHAR              in,
	OUT PUCHAR              out);

VOID mix_column(
	IN  PUCHAR              in,
	OUT PUCHAR              out);		

UCHAR RTMPCkipSbox(
	IN  UCHAR               a);
	

/*
	========================================================================

	Routine	Description:
		Convert from UCHAR[] to ULONG in a portable way 
		
	Arguments:
      pMICKey		pointer to MIC Key
		
	Return Value:
		None

	Note:
		
	========================================================================
*/
ULONG	RTMPTkipGetUInt32( 	
	IN	PUCHAR	pMICKey)
{  	
	ULONG	res = 0; 
	INT		i;
	
	for (i = 0; i < 4; i++) 
	{ 
		res |= (*pMICKey++) << (8 * i); 
	}

	return res; 
} 

/*
	========================================================================

	Routine	Description:
		Convert from ULONG to UCHAR[] in a portable way 
		
	Arguments:
      pDst			pointer to destination for convert ULONG to UCHAR[]
      val			the value for convert
		
	Return Value:
		None

	Note:
		
	========================================================================
*/
VOID	RTMPTkipPutUInt32(
	IN OUT	PUCHAR		pDst,
	IN		ULONG		val)					  
{ 	
	INT i;
	
	for(i = 0; i < 4; i++) 
	{ 
		*pDst++ = (UCHAR) (val & 0xff); 
		val >>= 8; 
	} 
} 

/*
	========================================================================

	Routine	Description:
		Set the MIC Key.
		
	Arguments:
      pAdapter		Pointer to our adapter
      pMICKey		pointer to MIC Key
		
	Return Value:
		None

	Note:
		
	========================================================================
*/
VOID RTMPTkipSetMICKey(  
	IN	PTKIP_KEY_INFO	pTkip,	
	IN	PUCHAR			pMICKey)
{ 
	// Set the key 
	pTkip->K0 = RTMPTkipGetUInt32(pMICKey); 
	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4); 
	// and reset the message 
	pTkip->L = pTkip->K0;
	pTkip->R = pTkip->K1;
	pTkip->nBytesInM = 0;
	pTkip->M = 0;
} 

/*
	========================================================================

	Routine	Description:
		Calculate the MIC Value.
		
	Arguments:
      pAdapter		Pointer to our adapter
      uChar			Append this uChar
		
	Return Value:
		None

	Note:
		
	========================================================================
*/
VOID	RTMPTkipAppendByte( 
	IN	PTKIP_KEY_INFO	pTkip,	
	IN	UCHAR 			uChar)
{ 
	// Append the byte to our word-sized buffer 
	pTkip->M |= (uChar << (8* pTkip->nBytesInM)); 
	pTkip->nBytesInM++; 
	// Process the word if it is full. 
	if( pTkip->nBytesInM >= 4 ) 
	{ 
		pTkip->L ^= pTkip->M; 
		pTkip->R ^= ROL32( pTkip->L, 17 ); 
		pTkip->L += pTkip->R; 
		pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8); 
		pTkip->L += pTkip->R; 
		pTkip->R ^= ROL32( pTkip->L, 3 ); 
		pTkip->L += pTkip->R; 
		pTkip->R ^= ROR32( pTkip->L, 2 ); 
		pTkip->L += pTkip->R; 
		// Clear the buffer 
		pTkip->M = 0; 
		pTkip->nBytesInM = 0; 
	} 
} 

/*
	========================================================================

	Routine	Description:
		Calculate the MIC Value.
		
	Arguments:
      pAdapter		Pointer to our adapter
      pSrc			Pointer to source data for Calculate MIC Value
      Len			Indicate the length of the source data
		
	Return Value:
		None

	Note:
		
	========================================================================
*/
VOID	RTMPTkipAppend( 
	IN	PTKIP_KEY_INFO	pTkip,	
	IN	PUCHAR			pSrc,
	IN	UINT			nBytes)						  
{ 
	// This is simple 
	while(nBytes > 0) 
	{ 
		RTMPTkipAppendByte(pTkip, *pSrc++); 
		nBytes--; 
	} 
} 

/*
	========================================================================

	Routine	Description:
		Get the MIC Value.
		
	Arguments:
      pAdapter		Pointer to our adapter
		
	Return Value:
		None

	Note:
		the MIC Value is store in pAdapter->PrivateInfo.MIC
	========================================================================
*/
VOID	RTMPTkipGetMIC( 
	IN	PTKIP_KEY_INFO	pTkip)
{ 
	// Append the minimum padding
	RTMPTkipAppendByte(pTkip, 0x5a );	
	RTMPTkipAppendByte(pTkip, 0 ); 
	RTMPTkipAppendByte(pTkip, 0 ); 
	RTMPTkipAppendByte(pTkip, 0 ); 
	RTMPTkipAppendByte(pTkip, 0 ); 
	// and then zeroes until the length is a multiple of 4 
	while( pTkip->nBytesInM != 0 ) 
	{ 
		RTMPTkipAppendByte(pTkip, 0 ); 
	} 
	// The appendByte function has already computed the result. 
	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
} 

/*
	========================================================================

	Routine	Description:
		Init Tkip function.	
		
	Arguments:
      pAdapter		Pointer to our adapter
		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
		KeyId		TK Key ID
		pTA			Pointer to transmitter address
		pMICKey		pointer to MIC Key
		
	Return Value:
		None

	Note:
	
	========================================================================
*/
VOID	RTMPInitTkipEngine(
	IN	PRTMP_ADAPTER	pAdapter,	
	IN	PUCHAR			pKey,
	IN	UCHAR			KeyId,
	IN	PUCHAR			pTA,
	IN	PUCHAR			pMICKey,
	IN	PUCHAR			pTSC,
	OUT	PULONG			pIV16,
	OUT	PULONG			pIV32)
{
	TKIP_IV	tkipIv;

	// Prepare 8 bytes TKIP encapsulation for MPDU
	NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
	tkipIv.IV16.field.rc0 = *(pTSC + 1);	
	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
	tkipIv.IV16.field.rc2 = *pTSC;
	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;  // 0: non-extended IV, 1: an extended IV
	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
//	tkipIv.IV32 = *(PULONG)(pTSC + 2);
	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);   // Copy IV

	*pIV16 = tkipIv.IV16.word;
	*pIV32 = tkipIv.IV32;
}

/*
	========================================================================

	Routine	Description:
		Init MIC Value calculation function which include set MIC key & 
		calculate first 16 bytes (DA + SA + priority +  0)
		
	Arguments:
      pAdapter		Pointer to our adapter
		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
		pDA			Pointer to DA address
		pSA			Pointer to SA address
		pMICKey		pointer to MIC Key
		
	Return Value:
		None

	Note:
	
	========================================================================
*/
VOID	RTMPInitMICEngine(
	IN	PRTMP_ADAPTER	pAdapter,	
	IN	PUCHAR			pKey,
	IN	PUCHAR			pDA,
	IN	PUCHAR			pSA,
	IN  UCHAR           UserPriority,
	IN	PUCHAR			pMICKey)
{
	ULONG Priority = UserPriority;

	// Init MIC value calculation
	RTMPTkipSetMICKey(&pAdapter->PrivateInfo.Tx, pMICKey);
	// DA
	RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
	// SA
	RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
	// Priority + 3 bytes of 0
	RTMPTkipAppend(&pAdapter->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
}

/*
	========================================================================

	Routine	Description:
		Compare MIC value of received MSDU
		
	Arguments:
		pAdapter	Pointer to our adapter
		pSrc        Pointer to the received Plain text data
		pDA			Pointer to DA address
		pSA			Pointer to SA address
		pMICKey		pointer to MIC Key
		Len         the length of the received plain text data exclude MIC value
		
	Return Value:
		TRUE        MIC value matched
		FALSE       MIC value mismatched
		
	Note:
	
	========================================================================
*/
BOOLEAN	RTMPTkipCompareMICValue(
	IN	PRTMP_ADAPTER	pAdapter,
	IN	PUCHAR			pSrc,
	IN	PUCHAR			pDA,
	IN	PUCHAR			pSA,
	IN	PUCHAR			pMICKey,
	IN	UINT			Len)
{
	UCHAR	OldMic[8];
	ULONG	Priority = 0;
	INT		i;

	// Init MIC value calculation
	RTMPTkipSetMICKey(&pAdapter->PrivateInfo.Rx, pMICKey);
	// DA
	RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
	// SA
	RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
	// Priority + 3 bytes of 0
	RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
	
	// Calculate MIC value from plain text data
	RTMPTkipAppend(&pAdapter->PrivateInfo.Rx, pSrc, Len);

	// Get MIC valude from received frame
	NdisMoveMemory(OldMic, pSrc + Len, 8);
	
	// Get MIC value from decrypted plain data
	RTMPTkipGetMIC(&pAdapter->PrivateInfo.Rx);
		
	// Move MIC value from MSDU, this steps should move to data path.
	// Since the MIC value might cross MPDUs.
	if(!NdisEqualMemory(pAdapter->PrivateInfo.Rx.MIC, OldMic, 8))
	{
		DBGPRINT(RT_DEBUG_ERROR, "! TKIP MIC Error !\n");  //MIC error.
		DBGPRINT(RT_DEBUG_INFO, "Orig MIC value =");  //MIC error.
		for (i = 0; i < 8; i++)
		{
			DBGPRINT(RT_DEBUG_INFO, "%02x:", OldMic[i]);  //MIC error.
		}
		DBGPRINT(RT_DEBUG_INFO, "\n");  //MIC error.
		DBGPRINT(RT_DEBUG_INFO, "Calculated MIC value =");  //MIC error.
		for (i = 0; i < 8; i++)
		{
			DBGPRINT(RT_DEBUG_INFO, "%02x:", pAdapter->PrivateInfo.Rx.MIC[i]);  //MIC error.
		}
		DBGPRINT(RT_DEBUG_INFO, "\n");  //MIC error.
		return (FALSE);
	}
	return (TRUE);

⌨️ 快捷键说明

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