AMPS:MD5模块源码解读

  MD5是用于确保信息传输完整一致性的一个哈希算法。

 其算法思想如下(摘自维基百科):

    MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

F(X,Y,Z) = (X\wedge{Y}) \vee (\neg{X} \wedge{Z})
G(X,Y,Z) = (X\wedge{Z}) \vee (Y \wedge \neg{Z})
H(X,Y,Z) = X \oplus Y \oplus Z
I(X,Y,Z) = Y \oplus (X \vee \neg{Z})

\oplus, \wedge, \vee, \neg 是 XORANDOR , NOT 的符号。

 一个MD5运算— 由类似的64次循环构成,分成4组16次。F 一个非线性函数;一个函数运算一次。Mi 表示一个 32-bits 的输入数据,Ki表示一个 32-bits 常数,用来完成每次不同的计算。

  

 下面是AMPS中MD5模块的源码(说真的,算法细节上还没完全理解清楚)

AMPS_MD5.h

#ifndef __HEADER_AMPS_MD5_H
#define __HEADER_AMPS_MD5_H

#ifdef __cplusplus
extern "C" {
#endif

#include "AMPS_Defines.h"
#include "AMPS_LinkList.h"

typedef struct _AMPSMD5Context      			t_AMPSMD5Context;

struct _AMPSMD5Context
{
	unsigned int	punTotal[2];
	unsigned int	punState[4];
	unsigned char	puchBuffer[64];
};

void* AMD5_Init(void* r_pvAMPSContext);
void AMD5_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSMD5Context);
int AMD5_Update(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchData, int r_nDataLength);
int AMD5_Final(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchMD5Hash);

#ifdef __cplusplus
}
#endif

#endif //__HEADER_AMPS_HEAP_H

AMPS_MD5.c

#include "AMPS_Core.h"
#include "AMPS_Defines.h"
#include "AMPS_MemMgt.h"
#include "AMPS_MD5.h"
#include "AMPS_LinkList.h"


#define GET_UINT32(n,b,i)                       \
{                                               \
	(n) = ( (unsigned int) (b)[(i)    ]       )       \
	| ( (unsigned int) (b)[(i) + 1] <<  8 )       \
	| ( (unsigned int) (b)[(i) + 2] << 16 )       \
	| ( (unsigned int) (b)[(i) + 3] << 24 );      \
}

#define PUT_UINT32(n,b,i)                       \
{                                               \
	(b)[(i)    ] = (unsigned char) ( (n)       );       \
	(b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
	(b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
	(b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
}

/*****************************************************************
函数名称: AMD5_Init
功能描述: MD5模块初始化
入参::
      void* r_pvAMPSContext AMPS应用上下文
出参:
      
返回值:
      int

*****************************************************************/

void* AMD5_Init(void* r_pvAMPSContext)
{
	t_AMPSMD5Context* poAMPSMD5Context = NULL;

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");

	poAMPSMD5Context = (t_AMPSMD5Context*)AMPS_InternalMalloc(sizeof(t_AMPSMD5Context));
	if(NULL == poAMPSMD5Context)
	{
		TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poMD5Context.\n");
		return NULL;
	}

	poAMPSMD5Context->punTotal[0] = 0;
	poAMPSMD5Context->punTotal[1] = 0;

    /*四个32位被称作链接变量*/
	poAMPSMD5Context->punState[0] = 0x67452301;
	poAMPSMD5Context->punState[1] = 0xEFCDAB89;
	poAMPSMD5Context->punState[2] = 0x98BADCFE;
	poAMPSMD5Context->punState[3] = 0x10325476;

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
	return poAMPSMD5Context;
}

/*****************************************************************
函数名称: AMD5_Cleanup
功能描述: MD5模块销毁
入参::
      void* r_pvAMPSContext AMPS应用上下文
      void* r_pvAMPSMD5Context MD5句柄
出参:
      
返回值:
      int

*****************************************************************/
void AMD5_Cleanup(void* r_pvAMPSContext, void* r_pvAMPSMD5Context)
{
	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
	
	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "AMPS_InternalFree called for r_pvAMPSMD5Context.\n");
	AMPS_InternalFree(r_pvAMPSMD5Context);

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}

/*****************************************************************
函数名称: AMD4_Process
功能描述: MD4处理过程
入参::
      void* r_pvAMPSContext AMPS应用上下文
      void* r_pvAMPSMD5Context MD5句柄
      unsigned char r_puchData[64] 64位二进制表示的填充信息
出参:
      
返回值:
      int

*****************************************************************/
void AMD4_Process(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char r_puchData[64])
{
	t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
	unsigned int X[16], A, B, C, D;

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");

	GET_UINT32( X[0],  r_puchData,  0 );
	GET_UINT32( X[1],  r_puchData,  4 );
	GET_UINT32( X[2],  r_puchData,  8 );
	GET_UINT32( X[3],  r_puchData, 12 );
	GET_UINT32( X[4],  r_puchData, 16 );
	GET_UINT32( X[5],  r_puchData, 20 );
	GET_UINT32( X[6],  r_puchData, 24 );
	GET_UINT32( X[7],  r_puchData, 28 );
	GET_UINT32( X[8],  r_puchData, 32 );
	GET_UINT32( X[9],  r_puchData, 36 );
	GET_UINT32( X[10], r_puchData, 40 );
	GET_UINT32( X[11], r_puchData, 44 );
	GET_UINT32( X[12], r_puchData, 48 );
	GET_UINT32( X[13], r_puchData, 52 );
	GET_UINT32( X[14], r_puchData, 56 );
	GET_UINT32( X[15], r_puchData, 60 );

#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

/*计算公式*/
#define P(a,b,c,d,k,s,t)                                \
	{                                                       \
	a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
	}

	A = poAMPSMD5Context->punState[0];
	B = poAMPSMD5Context->punState[1];
	C = poAMPSMD5Context->punState[2];
	D = poAMPSMD5Context->punState[3];

/*第一轮*/
#define F(x,y,z) (z ^ (x & (y ^ z)))

	P( A, B, C, D,  0,  7, 0xD76AA478 );
	P( D, A, B, C,  1, 12, 0xE8C7B756 );
	P( C, D, A, B,  2, 17, 0x242070DB );
	P( B, C, D, A,  3, 22, 0xC1BDCEEE );
	P( A, B, C, D,  4,  7, 0xF57C0FAF );
	P( D, A, B, C,  5, 12, 0x4787C62A );
	P( C, D, A, B,  6, 17, 0xA8304613 );
	P( B, C, D, A,  7, 22, 0xFD469501 );
	P( A, B, C, D,  8,  7, 0x698098D8 );
	P( D, A, B, C,  9, 12, 0x8B44F7AF );
	P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
	P( B, C, D, A, 11, 22, 0x895CD7BE );
	P( A, B, C, D, 12,  7, 0x6B901122 );
	P( D, A, B, C, 13, 12, 0xFD987193 );
	P( C, D, A, B, 14, 17, 0xA679438E );
	P( B, C, D, A, 15, 22, 0x49B40821 );

#undef F

/*第二轮*/
#define F(x,y,z) (y ^ (z & (x ^ y)))

	P( A, B, C, D,  1,  5, 0xF61E2562 );
	P( D, A, B, C,  6,  9, 0xC040B340 );
	P( C, D, A, B, 11, 14, 0x265E5A51 );
	P( B, C, D, A,  0, 20, 0xE9B6C7AA );
	P( A, B, C, D,  5,  5, 0xD62F105D );
	P( D, A, B, C, 10,  9, 0x02441453 );
	P( C, D, A, B, 15, 14, 0xD8A1E681 );
	P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
	P( A, B, C, D,  9,  5, 0x21E1CDE6 );
	P( D, A, B, C, 14,  9, 0xC33707D6 );
	P( C, D, A, B,  3, 14, 0xF4D50D87 );
	P( B, C, D, A,  8, 20, 0x455A14ED );
	P( A, B, C, D, 13,  5, 0xA9E3E905 );
	P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
	P( C, D, A, B,  7, 14, 0x676F02D9 );
	P( B, C, D, A, 12, 20, 0x8D2A4C8A );

#undef F

/*第三轮*/
#define F(x,y,z) (x ^ y ^ z)

	P( A, B, C, D,  5,  4, 0xFFFA3942 );
	P( D, A, B, C,  8, 11, 0x8771F681 );
	P( C, D, A, B, 11, 16, 0x6D9D6122 );
	P( B, C, D, A, 14, 23, 0xFDE5380C );
	P( A, B, C, D,  1,  4, 0xA4BEEA44 );
	P( D, A, B, C,  4, 11, 0x4BDECFA9 );
	P( C, D, A, B,  7, 16, 0xF6BB4B60 );
	P( B, C, D, A, 10, 23, 0xBEBFBC70 );
	P( A, B, C, D, 13,  4, 0x289B7EC6 );
	P( D, A, B, C,  0, 11, 0xEAA127FA );
	P( C, D, A, B,  3, 16, 0xD4EF3085 );
	P( B, C, D, A,  6, 23, 0x04881D05 );
	P( A, B, C, D,  9,  4, 0xD9D4D039 );
	P( D, A, B, C, 12, 11, 0xE6DB99E5 );
	P( C, D, A, B, 15, 16, 0x1FA27CF8 );
	P( B, C, D, A,  2, 23, 0xC4AC5665 );

#undef F

/*第四轮*/
#define F(x,y,z) (y ^ (x | ~z))

	P( A, B, C, D,  0,  6, 0xF4292244 );
	P( D, A, B, C,  7, 10, 0x432AFF97 );
	P( C, D, A, B, 14, 15, 0xAB9423A7 );
	P( B, C, D, A,  5, 21, 0xFC93A039 );
	P( A, B, C, D, 12,  6, 0x655B59C3 );
	P( D, A, B, C,  3, 10, 0x8F0CCC92 );
	P( C, D, A, B, 10, 15, 0xFFEFF47D );
	P( B, C, D, A,  1, 21, 0x85845DD1 );
	P( A, B, C, D,  8,  6, 0x6FA87E4F );
	P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
	P( C, D, A, B,  6, 15, 0xA3014314 );
	P( B, C, D, A, 13, 21, 0x4E0811A1 );
	P( A, B, C, D,  4,  6, 0xF7537E82 );
	P( D, A, B, C, 11, 10, 0xBD3AF235 );
	P( C, D, A, B,  2, 15, 0x2AD7D2BB );
	P( B, C, D, A,  9, 21, 0xEB86D391 );

#undef F

	poAMPSMD5Context->punState[0] += A;
	poAMPSMD5Context->punState[1] += B;
	poAMPSMD5Context->punState[2] += C;
	poAMPSMD5Context->punState[3] += D;

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}

/*****************************************************************
函数名称: AMD5_Update
功能描述: MD5处理过程
入参::
      void* r_pvAMPSContext AMPS应用上下文
      void* r_pvAMPSMD5Context MD5句柄
      unsigned char r_puchData[64] 64位二进制表示的填充信息
      int r_nDataLength 数据长度
出参:
      
返回值:
      int

*****************************************************************/
int AMD5_Update(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchData, int r_nDataLength)
{
	t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
	unsigned int left, fill;

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");

	if( ! r_nDataLength ) return AMPS_ERROR_FAILURE;

	left = poAMPSMD5Context->punTotal[0] & 0x3F;
	fill = 64 - left;

	poAMPSMD5Context->punTotal[0] += r_nDataLength;
	poAMPSMD5Context->punTotal[0] &= 0xFFFFFFFF;

	if( poAMPSMD5Context->punTotal[0] < (unsigned int)r_nDataLength )
		poAMPSMD5Context->punTotal[1]++;

	if( left && (unsigned int)r_nDataLength >= fill )
	{
		memcpy((void*)(poAMPSMD5Context->puchBuffer + left), (void*)r_puchData, fill );
		AMD4_Process(r_pvAMPSContext, poAMPSMD5Context, poAMPSMD5Context->puchBuffer );
		r_nDataLength -= fill;
		r_puchData  += fill;
		left = 0;
	}

	while( r_nDataLength >= 64 )
	{
		AMD4_Process(r_pvAMPSContext, poAMPSMD5Context, r_puchData);
		r_nDataLength -= 64;
		r_puchData  += 64;
	}

	if( r_nDataLength )
	{
		memcpy((void*)(poAMPSMD5Context->puchBuffer + left), (void*)r_puchData, r_nDataLength );
	}

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
	return AMPS_SUCCESS;
}

/*64位填充信息*/
static unsigned char md5_padding[64] =
{
	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

/*****************************************************************
函数名称: AMD5_Final
功能描述: MD5计算函数
入参::
      void* r_pvAMPSContext AMPS应用上下文
      void* r_pvAMPSMD5Context MD5句柄
      unsigned char* r_puchMD5Hash md5值
出参:
      unsigned char* r_puchMD5Hash md5值
      
返回值:
      int

*****************************************************************/
int AMD5_Final(void* r_pvAMPSContext, void* r_pvAMPSMD5Context, unsigned char* r_puchMD5Hash)
{
	t_AMPSMD5Context* poAMPSMD5Context = r_pvAMPSMD5Context;
	unsigned int last, padn;
	unsigned int high, low;
	unsigned char msglen[8];

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");

	high = ( poAMPSMD5Context->punTotal[0] >> 29 )
		| ( poAMPSMD5Context->punTotal[1] <<  3 );
	low  = ( poAMPSMD5Context->punTotal[0] <<  3 );

	PUT_UINT32( low,  msglen, 0 );
	PUT_UINT32( high, msglen, 4 );

	last = poAMPSMD5Context->punTotal[0] & 0x3F;
	padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );

	AMD5_Update(r_pvAMPSContext, poAMPSMD5Context, md5_padding, padn );
	AMD5_Update(r_pvAMPSContext, poAMPSMD5Context, msglen, 8 );

	PUT_UINT32( poAMPSMD5Context->punState[0], r_puchMD5Hash,  0 );
	PUT_UINT32( poAMPSMD5Context->punState[1], r_puchMD5Hash,  4 );
	PUT_UINT32( poAMPSMD5Context->punState[2], r_puchMD5Hash,  8 );
	PUT_UINT32( poAMPSMD5Context->punState[3], r_puchMD5Hash, 12 );

	TRACE( MD5_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
	return AMPS_SUCCESS;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值