md5.c

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

C
1,418
字号
	
	// [equal to 4294967296*abs(sin(index))]
    static ULONG MD5Table[64] = 
	{ 
		0xd76aa478,	0xe8c7b756,	0x242070db,	0xc1bdceee,	
		0xf57c0faf,	0x4787c62a,	0xa8304613, 0xfd469501,	
		0x698098d8,	0x8b44f7af,	0xffff5bb1,	0x895cd7be,
    	0x6b901122,	0xfd987193,	0xa679438e,	0x49b40821,
    	
    	0xf61e2562,	0xc040b340,	0x265e5a51,	0xe9b6c7aa,
    	0xd62f105d,	0x02441453,	0xd8a1e681,	0xe7d3fbc8,
    	0x21e1cde6,	0xc33707d6,	0xf4d50d87,	0x455a14ed,
    	0xa9e3e905,	0xfcefa3f8,	0x676f02d9,	0x8d2a4c8a,
    	           
    	0xfffa3942,	0x8771f681,	0x6d9d6122,	0xfde5380c,
    	0xa4beea44,	0x4bdecfa9,	0xf6bb4b60,	0xbebfbc70,
    	0x289b7ec6,	0xeaa127fa,	0xd4ef3085,	0x04881d05,
    	0xd9d4d039,	0xe6db99e5,	0x1fa27cf8,	0xc4ac5665,
    	           
    	0xf4292244,	0x432aff97,	0xab9423a7,	0xfc93a039,
   		0x655b59c3,	0x8f0ccc92,	0xffeff47d,	0x85845dd1,
    	0x6fa87e4f,	0xfe2ce6e0,	0xa3014314,	0x4e0811a1,
    	0xf7537e82,	0xbd3af235,	0x2ad7d2bb,	0xeb86d391
	};
 
				
    for (i=0; i<4; i++)
        Reg[i]=Buf[i];
			
				
    // 64 steps in MD5 algorithm
    for (i=0; i<16; i++)                    
    {
        MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],               
                MD5Table[i], LShiftVal[i & 0x3]);

        // one-word right shift
        Temp   = Reg[3]; 
        Reg[3] = Reg[2];
        Reg[2] = Reg[1];
        Reg[1] = Reg[0];
        Reg[0] = Temp;            
    }
    for (i=16; i<32; i++)                    
    {
        MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf], 
                MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);    

        // one-word right shift
        Temp   = Reg[3]; 
        Reg[3] = Reg[2];
        Reg[2] = Reg[1];
        Reg[1] = Reg[0];
        Reg[0] = Temp;           
    }
    for (i=32; i<48; i++)                    
    {
        MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf], 
                MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);        

        // one-word right shift
        Temp   = Reg[3]; 
        Reg[3] = Reg[2];
        Reg[2] = Reg[1];
        Reg[1] = Reg[0];
        Reg[0] = Temp;          
    }
    for (i=48; i<64; i++)                    
    {
        MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf], 
                MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);   

        // one-word right shift
        Temp   = Reg[3]; 
        Reg[3] = Reg[2];
        Reg[2] = Reg[1];
        Reg[1] = Reg[0];
        Reg[0] = Temp;           
    }
    
      
    // (temporary)output
    for (i=0; i<4; i++)
        Buf[i] += Reg[i];

}



/* =========================  SHA-1 implementation ========================== */
// four base functions for SHA-1
#define SHA1_F1(b, c, d)    (((b) & (c)) | ((~b) & (d)))         
#define SHA1_F2(b, c, d)    ((b) ^ (c) ^ (d)) 
#define SHA1_F3(b, c, d)    (((b) & (c)) | ((b) & (d)) | ((c) & (d)))


#define SHA1Step(f, a, b, c, d, e, w, k)    \
    ( e	+= ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
      b = CYCLIC_LEFT_SHIFT(b, 30) )

//Initiate SHA-1 Context satisfied in RFC 3174  
VOID SHAInit(SHA_CTX *pCtx)
{
    pCtx->Buf[0]=0x67452301;
    pCtx->Buf[1]=0xefcdab89;
    pCtx->Buf[2]=0x98badcfe;
    pCtx->Buf[3]=0x10325476;
    pCtx->Buf[4]=0xc3d2e1f0;
    
    pCtx->LenInBitCount[0]=0;
    pCtx->LenInBitCount[1]=0;
}

/*
 *  Function Description:
 *      Update SHA-1 Context, allow of an arrary of octets as the next
 *      portion of the message
 *      
 *  Arguments:
 *      pCtx		Pointer	to SHA-1 context
 * 	    pData       Pointer to input data
 *      LenInBytes  The length of input data (unit: byte)
 *
 *  Return Value:
 *      error       indicate more than pow(2,64) bits of data  
 *
 *  Note:
 *      Called after SHAInit or SHAUpdate(itself)   
 */
UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, ULONG LenInBytes)
{
    ULONG TfTimes;
    ULONG temp1,temp2;
	unsigned int i;
	UCHAR err=1;
    
    temp1 = pCtx->LenInBitCount[0];
    temp2 = pCtx->LenInBitCount[1];

    pCtx->LenInBitCount[0] = (ULONG) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
    if (pCtx->LenInBitCount[0] < temp1)
        pCtx->LenInBitCount[1]++;   //carry in


    pCtx->LenInBitCount[1] = (ULONG) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
    if (pCtx->LenInBitCount[1] < temp2)
        return (err);   //check total length of original data
 

    // mod 64 bytes
    temp1 = (temp1 >> 3) & 0x3f;  
    
    // process lacks of 64-byte data 
    if (temp1) 
    {
        UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
        
        if ((temp1+LenInBytes) < 64)
        {
            NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);   
            return (0);
        }
        
        NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);              
        byteReverse((UCHAR *)pCtx->Input, 16);               
        
        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
        SHATransform(pCtx->Buf, (ULONG *)pCtx->Input);

        pData += 64-temp1;
        LenInBytes -= 64-temp1; 
    } // end of if (temp1)
    
     
    TfTimes = (LenInBytes >> 6);

    for (i=TfTimes; i>0; i--)
    {
        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
        byteReverse((UCHAR *)pCtx->Input, 16);
        
        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
        SHATransform(pCtx->Buf, (ULONG *)pCtx->Input);
        pData += 64;
        LenInBytes -= 64;
    } // end of for

    // buffering lacks of 64-byte data
    if(LenInBytes)
        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);

	return (0);

}

// Append padding bits and length of original message in the tail 
// The message digest has to be completed in the end 
VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
{
    UCHAR Remainder;
    UCHAR PadLenInBytes;
    UCHAR *pAppend=0;
    unsigned int i;

    Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);

    pAppend = (UCHAR *)pCtx->Input + Remainder;

    PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
    
    // padding bits without crossing block(64-byte based) boundary
    if (Remainder < 56)
    {       
        *pAppend = 0x80;
        PadLenInBytes --;
        
        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); 
		 
		// add data-length field, from high to low
        for (i=0; i<4; i++)
        {
        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
      	}
      	
        byteReverse((UCHAR *)pCtx->Input, 16);
        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
        SHATransform(pCtx->Buf, (ULONG *)pCtx->Input);
    } // end of if
    
    // padding bits with crossing block(64-byte based) boundary
    else
    {
        // the first block ===
        *pAppend = 0x80;
        PadLenInBytes --;
        
        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); 
        PadLenInBytes -= (64 - Remainder - 1);
        
        byteReverse((UCHAR *)pCtx->Input, 16);
        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
        SHATransform(pCtx->Buf, (ULONG *)pCtx->Input);


        // the second block ===
        NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); 
			
		// add data-length field
		for (i=0; i<4; i++)
        {
        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
      	}
      	
        byteReverse((UCHAR *)pCtx->Input, 16);
        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); 
        SHATransform(pCtx->Buf, (ULONG *)pCtx->Input);
    } // end of else
	
		
    //Output, bytereverse
    for (i=0; i<20; i++)
    {
        Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
    }
    
    NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free 
}


// The central algorithm of SHA-1, consists of four rounds and 
// twenty steps per round
VOID SHATransform(ULONG Buf[5], ULONG Mes[20])
{
    ULONG Reg[5],Temp; 
	unsigned int i;
    ULONG W[80]; 
   
    static ULONG SHA1Table[4] = { 0x5a827999, 0x6ed9eba1, 
                                  0x8f1bbcdc, 0xca62c1d6 };
 
    Reg[0]=Buf[0];
	Reg[1]=Buf[1];
	Reg[2]=Buf[2];
	Reg[3]=Buf[3];
	Reg[4]=Buf[4];

    //the first octet of a word is stored in the 0th element, bytereverse
	for(i = 0; i < 16; i++)
    { 
    	W[i]  = (Mes[i] >> 24) & 0xff;
        W[i] |= (Mes[i] >> 8 ) & 0xff00;
        W[i] |= (Mes[i] << 8 ) & 0xff0000;
        W[i] |= (Mes[i] << 24) & 0xff000000;
    }
    
		 
    for	(i = 0; i < 64; i++)
	    W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
	    
    
    // 80 steps in SHA-1 algorithm
    for (i=0; i<80; i++)                    
    {
        if (i<20)
            SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 
                     W[i], SHA1Table[0]);
        
        else if (i>=20 && i<40)
            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 
                     W[i], SHA1Table[1]);
			
		else if (i>=40 && i<60)
            SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 
                      W[i], SHA1Table[2]);
			
        else
            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], 
                     W[i], SHA1Table[3]);
			

       // one-word right shift
		Temp   = Reg[4];
        Reg[4] = Reg[3];
        Reg[3] = Reg[2];
        Reg[2] = Reg[1];
        Reg[1] = Reg[0];
        Reg[0] = Temp;       
  
    } // end of for-loop


    // (temporary)output
    for (i=0; i<5; i++)
        Buf[i] += Reg[i];
    
}


/* =========================  AES En/Decryption ========================== */

/* forward S-box */
static uint32 FSb[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,

⌨️ 快捷键说明

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