md5.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,418 行 · 第 1/4 页

C
1,418
字号
		break;
	}

	/* setup decryption	round keys */

	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 = 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 aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
{
	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;

	RK = 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 aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
{
	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;

	RK = 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 );
}

/*
	========================================================================
	
	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 */
}

/*
* F(P, S, c, i) = U1 xor U2 xor ... Uc 
* U1 = PRF(P, S || Int(i)) 
* U2 = PRF(P, U1) 
* Uc = PRF(P, Uc-1) 
*/ 

void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output) 
{ 
    unsigned char digest[36], digest1[SHA_DIGEST_LEN]; 
    int i, j; 

    /* U1 = PRF(P, S || int(i)) */ 
    memcpy(digest, ssid, ssidlength); 
    digest[ssidlength] = (unsigned char)((count>>24) & 0xff); 
    digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff); 
    digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff); 
    digest[ssidlength+3] = (unsigned char)(count & 0xff); 
    HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update

    /* output = U1 */ 
    memcpy(output, digest1, SHA_DIGEST_LEN); 

    for (i = 1; i < iterations; i++) 
    { 
        /* Un = PRF(P, Un-1) */ 
        HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
        memcpy(digest1, digest, SHA_DIGEST_LEN); 

        /* output = output xor Un */ 
        for (j = 0; j < SHA_DIGEST_LEN; j++) 
        { 
            output[j] ^= digest[j]; 
        } 
    } 
}
/* 
* password - ascii string up to 63 characters in length 
* ssid - octet string up to 32 octets 
* ssidlength - length of ssid in octets 
* output must be 40 octets in length and outputs 256 bits of key 
*/ 
int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output) 
{ 
    if ((strlen(password) > 63) || (ssidlength > 32)) 
        return 0; 

    F(password, ssid, ssidlength, 4096, 1, output); 
    F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]); 
    return 1; 
}


⌨️ 快捷键说明

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