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

📄 cmm_aes.c

📁 ralink 2870 usb无线网卡 最新驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	if(	KT_init	)	{		for( i = 0;	i <	256; i++ )		{			KT0[i] = RT0[ FSb[i] ];			KT1[i] = RT1[ FSb[i] ];			KT2[i] = RT2[ FSb[i] ];			KT3[i] = RT3[ FSb[i] ];		}		KT_init	= 0;	}	SK = (uint32 *) ctx->drk;	*SK++ =	*RK++;	*SK++ =	*RK++;	*SK++ =	*RK++;	*SK++ =	*RK++;	for( i = 1;	i <	ctx->nr; i++ )	{		RK -= 8;		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^				KT1[ (uint8) ( *RK >> 16 ) ] ^				KT2[ (uint8) ( *RK >>  8 ) ] ^				KT3[ (uint8) ( *RK		 ) ]; RK++;		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^				KT1[ (uint8) ( *RK >> 16 ) ] ^				KT2[ (uint8) ( *RK >>  8 ) ] ^				KT3[ (uint8) ( *RK		 ) ]; RK++;		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^				KT1[ (uint8) ( *RK >> 16 ) ] ^				KT2[ (uint8) ( *RK >>  8 ) ] ^				KT3[ (uint8) ( *RK		 ) ]; RK++;		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^				KT1[ (uint8) ( *RK >> 16 ) ] ^				KT2[ (uint8) ( *RK >>  8 ) ] ^				KT3[ (uint8) ( *RK		 ) ]; RK++;	}	RK -= 8;	*SK++ =	*RK++;	*SK++ =	*RK++;	*SK++ =	*RK++;	*SK++ =	*RK++;	return(	0 );}/* AES 128-bit block encryption	routine	*/void rt_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] ){	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;	RK = (uint32 *) ctx->erk;	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\{												\	RK += 4;									\												\	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\				 FT3[ (uint8) (	Y3		 ) ];	\												\	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\				 FT3[ (uint8) (	Y0		 ) ];	\												\	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\				 FT3[ (uint8) (	Y1		 ) ];	\												\	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\				 FT3[ (uint8) (	Y2		 ) ];	\}	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */	if(	ctx->nr	> 10 )	{		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/	}	if(	ctx->nr	> 12 )	{		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/	}	/* last	round */	RK += 4;	X0 = RK[0] ^ ( FSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^				 ( FSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^				 ( FSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^				 ( FSb[	(uint8)	( Y3	   ) ]		 );	X1 = RK[1] ^ ( FSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^				 ( FSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^				 ( FSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^				 ( FSb[	(uint8)	( Y0	   ) ]		 );	X2 = RK[2] ^ ( FSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^				 ( FSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^				 ( FSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^				 ( FSb[	(uint8)	( Y1	   ) ]		 );	X3 = RK[3] ^ ( FSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^				 ( FSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^				 ( FSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^				 ( FSb[	(uint8)	( Y2	   ) ]		 );	PUT_UINT32(	X0,	output,	 0 );	PUT_UINT32(	X1,	output,	 4 );	PUT_UINT32(	X2,	output,	 8 );	PUT_UINT32(	X3,	output,	12 );}/* AES 128-bit block decryption	routine	*/void rt_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] ){	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;	RK = (uint32 *) ctx->drk;	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\{												\	RK += 4;									\												\	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\				 RT3[ (uint8) (	Y1		 ) ];	\												\	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\				 RT3[ (uint8) (	Y2		 ) ];	\												\	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\				 RT3[ (uint8) (	Y3		 ) ];	\												\	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\				 RT3[ (uint8) (	Y0		 ) ];	\}	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */	if(	ctx->nr	> 10 )	{		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/	}	if(	ctx->nr	> 12 )	{		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/	}	/* last	round */	RK += 4;	X0 = RK[0] ^ ( RSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^				 ( RSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^				 ( RSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^				 ( RSb[	(uint8)	( Y1	   ) ]		 );	X1 = RK[1] ^ ( RSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^				 ( RSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^				 ( RSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^				 ( RSb[	(uint8)	( Y2	   ) ]		 );	X2 = RK[2] ^ ( RSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^				 ( RSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^				 ( RSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^				 ( RSb[	(uint8)	( Y3	   ) ]		 );	X3 = RK[3] ^ ( RSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^				 ( RSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^				 ( RSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^				 ( RSb[	(uint8)	( Y0	   ) ]		 );	PUT_UINT32(	X0,	output,	 0 );	PUT_UINT32(	X1,	output,	 4 );	PUT_UINT32(	X2,	output,	 8 );	PUT_UINT32(	X3,	output,	12 );}/*    ==========================================================================    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 UINT32    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;    rt_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);            rt_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	UINT32   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];	}	rt_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);			rt_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);}/* =======  The related function of AES-128-CMAC  ======= */VOID leftshift_onebit(	IN  PUCHAR 	input, 	OUT PUCHAR 	output){	INT i;	UCHAR overflow = 0;	for (i=15; i>=0; i--)	{		output[i] = input[i] << 1;		output[i] |= overflow;		overflow = (input[i] & 0x80) ? 1 : 0;	}	}VOID do_padding(	IN	PUCHAR	lastb,	OUT	PUCHAR	pad,	IN  INT		len){	INT	j;	for (j=0; j<16; j++)	{		if (j < len)			pad[j] = lastb[j];		else if (j == len)			pad[j] = 0x80;		else			pad[j] = 0x00;	}}/* *	The Subkey Generation Algorithm  */VOID generate_subkey(	IN 	PUCHAR key,	OUT	PUCHAR K1, 	OUT PUCHAR K2){	aes_context aesctx;	UCHAR aes_128_key[16];		UCHAR const_Zero[16];		UCHAR tmp[16];	UCHAR const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,					      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};								// initial the key material		memset(const_Zero, 0, 16);	memset(aes_128_key, 0, 16);	// AES-128 with key is applied to an all-zero input block	rt_aes_set_key(&aesctx, key, 128);	rt_aes_encrypt(&aesctx, const_Zero, aes_128_key);	// derive K1(128-bit first subkey) and K2(128-bit second subkey), refer to rfc-4493 ch 2.3		if ((aes_128_key[0] & 0x80) == 0)	{		leftshift_onebit(aes_128_key, K1);	}	else	{		leftshift_onebit(aes_128_key, tmp);		xor_128(tmp, const_Rb, K1);	}	if ((K1[0] & 0x80) == 0)	{		leftshift_onebit(K1, K2);	}	else	{		leftshift_onebit(K1, tmp);		xor_128(tmp, const_Rb, K2);	}	}/* *	AES-CMAC Algorithm. (refer to rfc-4493 and SP800-38B) *   *	Input : key 		(128-bit key) *			input		(message to be authenticated) *			len			(length of the message in octets) *			 *	output: mac			(message authentication code) */VOID AES_128_CMAC(	IN	PUCHAR	key,	IN	PUCHAR	input,	IN	INT		len,	OUT	PUCHAR	mac){	UCHAR	X[16], Y[16], M_last[16], padded[16];	UCHAR	K1[16], K2[16];	aes_context aesctx;	INT		n, i, flag;	generate_subkey(key, K1, K2);		n = (len+15) / 16;		// n is number of rounds	if (n == 0)	{		n = 1;		flag = 0;	}	else	{					if ((len%16) == 0)			flag = 1;			// indicate that last block is a complete block				else			flag = 0;			// indicate that last block is not a complete block	}	if (flag)	{		xor_128(&input[16*(n-1)], K1, M_last);	}	else	{		do_padding(&input[16*(n-1)], padded, len%16);		xor_128(padded, K2, M_last);	}	memset(X, 0, 16);	for (i=0; i<n-1; i++)	{		xor_128(X, &input[16*i], Y);		rt_aes_set_key(&aesctx, key, 128);		rt_aes_encrypt(&aesctx, Y, X);	}	xor_128(X, M_last, Y);	rt_aes_set_key(&aesctx, key, 128);	rt_aes_encrypt(&aesctx, Y, X);	for (i=0; i<16; i++)	{		mac[i] = X[i];	}}/* =======  The related function of AES-128-CMAC  ======= */

⌨️ 快捷键说明

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