MD5 is a hash algorithm used to ensure the integrity and consistency of information transmission.
The algorithm IDEA is as follows (from Wikipedia ):
MD5 is an algorithm that outputs a fixed length of 128-bits. After the program flow, four 32-bit data are generated, and finally merged into a 128-bits hash. The basic method is to calculate the remainder, take the remainder, adjust the length, and perform cyclic operations with the link variable. Result.
YesXOR,And,Or,Not.
An MD5 operation is composed of 64 similar loops and divided into four groups of 16 times. F is a non-linear function; a function is computed once. Mi indicates
32-bits input data, Ki indicates
The 32-bits constant is used to complete different calculations each time.
The following is the source code of the MD5 module in amps (to be honest, the algorithm details are not fully understood yet)
Amps_md5.h
#ifndef __HEADER_AMPS_MD5_H#define __HEADER_AMPS_MD5_H#ifdef __cplusplusextern "C" {#endif#include "AMPS_Defines.h"#include "AMPS_LinkList.h"typedef struct _AMPSMD5Context t_AMPSMD5Context;struct _AMPSMD5Context{unsigned intpunTotal[2];unsigned intpunState[4];unsigned charpuchBuffer[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 ); \}/************************************* * *************************** Function Name: amd5_init Function Description: MD5 module initialization input parameter: void * r_pvampscontext amps application context output parameter: return value: 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 *) equals (sizeof (t_ampsmd5context); If (null = poampsmd5context) {trace (md5_trace_id (r_pvampscontext), ignore, "amps_internalmalloc failed for pomd5context. \ n "); return NULL;} poampsmd5context-> puntotal [0] = 0; poampsmd5context-> puntotal [1] = 0;/* Four 32-bit links Variable */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 ;} /*************************************** * ************************** Function Name: amd5_cleanup Function Description: MD5 module destruction input parameter: void * r_pvampscontext Amps application context void * r_pvampsmd5context MD5 handle output parameter: return value: 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_pv Ampsmd5context); trace (md5_trace_id (r_pvampscontext), amps_trace_level_info, "leaving. \ n ");} /*************************************** * ************************** Function Name: amd4_process Function Description: input parameter of the md4 processing process: void * r_pvampscontext amps application context void * r_pvampsmd5context MD5 handle unsigned char r_puchdata [64] output parameter of the 64-bit binary representation: return value: 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_puchda Ta, 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 & 0 xffffffff)> (32-N ))) /* formula */# 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]; /* First round */# 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,, 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, 0xfd9 87193); P (c, d, A, B, 14, 17, 0xa679438e); P (B, c, d, A, 15, 22, 0x49b40821 ); # undef f/* Second round */# 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, 0xe 7d3fbc8); 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/* Third round */# 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 (, 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, 0xeaa0000fa); 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,, b, c, 12, 11, 0xe6db99e5); P (c, d, A, B, 15, 16, 0x1fa27cf8); P (B, c, d, A, 2, 23, 0xc4ac5665); # undef f/* Fourth Round */# 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 fpoampsmd5context-> 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 ");}/*********** **************************************** * ************* Function Name: amd5_update Function Description: MD5 processing input parameters :: void * r_pvampscontext amps application context void * r_pvampsmd5context MD5 handle unsigned char r_puchdata [64] fill information in 64-bit binary representation int r_ndatalength Data Length output parameter: return value: int *************************************** * ************************/INT amd5_update (void * r_pvampscontext, void * r_pvampsmd5context, unsigned char * r_puchdata, int r_ndatale Ngth) {t_ampsmd5context * poampsmd5context = r_pvampsmd5context; unsigned int left, fill; trace (md5_trace_id (r_pvampscontext), locate, "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] & = 0 xffffffff; 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); bytes-= fill; r_puchdata + = fill; left = 0;} while (Bytes> = 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_tra Ce_id (r_pvampscontext), amps_trace_level_info, "leaving. \ n "); Return amps_success;}/* 64-bit filling information */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 }; /*************************************** * ************************** Function Name: amd5 _ Final Function Description: MD5 calculation function input parameter: void * r_pvampscontext amps application context void * r_pvampsmd5context MD5 handle unsigned char * r_puchmd5hash MD5 value output parameter: unsigned char * r_puchmd5hash MD5 return value: 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], success, 0); put_uint32 (poampsmd5context-> punstate [1], fail, 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, "leav. \ n "); Return amps_success ;}