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

📄 md5.c

📁 移动短信网关协议CMPPv2.0的封装实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Functions to compute MD5 message digest of files or memory blocks
 * according to the definition of MD5 in RFC 1321 from April 1992.
 * Copyright (C) 1995, 1996 Free Software Foundation, Inc.  NOTE: The
 * canonical source of this file is maintained with the GNU C Library.
 * Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 * Modified by Gray Watson <http://256.com/gray/>, 1997.
 *
 * $Id: md5.c,v 1.5 2000/03/09 04:06:41 gray Exp $
 */

/*
 * NOTE: during quick performance tests on a Sun Sparc Ultra 1 and an
 * Alpha 255 300, these functions performed upwards of 3mb/sec
 * including disk I/O time.
 */

/*
 * MD5 Test Suite from RFC1321: http://ds.internic.net:/rfc/rfc1321.txt
 *
 * MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
 * MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
 * MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
 * MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
 * MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
 * MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
 * d174ab98d277d9f5a5611c2c9f419d9f
 * MD5 ("123456789012345678901234567890123456789012345678901234567890123456
 * 78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
 */
#include "md5.h"

/*
 * Local defines for the md5 functions.
 *
 * $Id: md5_loc.h,v 1.3 2000/03/09 04:06:41 gray Exp $
 */

/*
 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 * rights reserved.
 *
 * License to copy and use this software is granted provided that it is
 * identified as the "RSA Data Security, Inc. MD5 Message-Digest
 * Algorithm" in all material mentioning or referencing this software
 * or this function.
 *
 * License is also granted to make and use derivative works provided that
 * such works are identified as "derived from the RSA Data Security,
 * Inc. MD5 Message-Digest Algorithm" in all material mentioning or
 * referencing the derived work.
 *
 * RSA Data Security, Inc. makes no representations concerning either the
 * merchantability of this software or the suitability of this
 * software for any particular purpose. It is provided "as is" without
 * express or implied warranty of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * documentation and/or software.
 */

#ifndef __MD5_LOC_H__
#define __MD5_LOC_H__

#define HEX_STRING	"0123456789abcdef"	/* to convert to hex */
#define BLOCK_SIZE_MASK	(MD5_BLOCK_SIZE - 1)

/* #define __BIG_ENDIAN__ */
#ifdef __BIG_ENDIAN__
/*
 * big endian - big is better
 */
#define SWAP(n)	(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
/*
 * little endian
 */
#define SWAP(n) (n)
#endif

/*
 * These are the four functions used in the four steps of the MD5
 * algorithm and defined in the RFC 1321.  The first function is a
 * little bit optimized (as found in Colin Plumbs public domain
 * implementation).
 */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d)	(d ^ (b & (c ^ d)))
#define FG(b, c, d)	FF(d, b, c)
#define FH(b, c, d)	(b ^ c ^ d)
#define FI(b, c, d)	(c ^ (b | ~d))

/*
 * It is unfortunate that C does not provide an operator for cyclic
 * rotation.  Hope the C compiler is smart enough.  -- Modified to
 * remove the w = at the front - Gray 2/97
 */
#define CYCLIC(w, s)	((w << s) | (w >> (32 - s)))

/*
 * First Round: using the given function, the context and a constant
 * the next context is computed.  Because the algorithms processing
 * unit is a 32-bit word and it is determined to work on words in
 * little endian byte order we perhaps have to change the byte order
 * before the computation.  To reduce the work for the next steps we
 * store the swapped words in the array CORRECT_WORDS. -- Modified to
 * fix the handling of unaligned buffer spaces - Gray 7/97
 */
#define OP1(a, b, c, d, b_p, c_p, s, T)				\
     do {							\
       memcpy(c_p, b_p, sizeof(md5_uint32));       		\
       *c_p = SWAP(*c_p);					\
       a += FF (b, c, d) + *c_p + T;				\
       a = CYCLIC (a, s);					\
       a += b;							\
       b_p = (char *)b_p + sizeof(md5_uint32);			\
       c_p++;							\
    } while (0)

/*
 * Second to Fourth Round: we have the possibly swapped words in
 * CORRECT_WORDS.  Redefine the macro to take an additional first
 * argument specifying the function to use.
 */
#define OP234(FUNC, a, b, c, d, k, s, T)		\
    do { 						\
      a += FUNC (b, c, d) + k + T;			\
      a = CYCLIC (a, s);				\
      a += b;						\
    } while (0)

#endif /* __MD5_LOC_H__ */

/****************************** local routines *******************************/

/*
 * process_block
 *
 * DESCRIPTION:
 *
 * Process a block of bytes into a MD5 state structure.
 *
 * RETURNS:
 *
 * None.
 *
 * ARGUMENTS:
 *
 * md5_p - Pointer to MD5 structure from which we are getting the result.
 *
 * buffer - A buffer of bytes whose MD5 signature we are calculating.
 *
 * buf_len - The length of the buffer.
 */
static void	process_block(md5_t *md5_p, const void *buffer, const unsigned int buf_len)
{
	md5_uint32	correct[16];
	const void	*buf_p = buffer, *end_p;
	unsigned int	words_n;
	md5_uint32	A, B, C, D;
	
	words_n = buf_len / sizeof(md5_uint32);
	end_p = (char *)buf_p + words_n * sizeof(md5_uint32);
	
	A = md5_p->md_A;
	B = md5_p->md_B;
	C = md5_p->md_C;
	D = md5_p->md_D;

	/*
	 * First increment the byte count.  RFC 1321 specifies the possible
	 * length of the file up to 2^64 bits.  Here we only compute the
	 * number of bytes with a double word increment.  Modified to do
	 * this to better avoid overflows in the lower word -- Gray 10/97.
	 */
	if (md5_p->md_total[0] > MAX_MD5_UINT32 - buf_len) 
	{
		md5_p->md_total[1]++;
		md5_p->md_total[0] -= (MAX_MD5_UINT32 - buf_len);
	}
	else 
	{
		md5_p->md_total[0] += buf_len;
	}

	/*
	 * Process all bytes in the buffer with MD5_BLOCK bytes in each
	 * round of the loop.
	 */
	while (buf_p < end_p) 
	{
		md5_uint32	A_save, B_save, C_save, D_save;
		md5_uint32	*corr_p = correct;
		
		A_save = A;
		B_save = B;
		C_save = C;
		D_save = D;
		
		/*
		 * Before we start, one word to the strange constants.  They are
		 * defined in RFC 1321 as
		 *
		 * T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..MD5_BLOCK
		 */
		
		/* Round 1. */
		OP1 (A, B, C, D, buf_p, corr_p,  7, 0xd76aa478);
		OP1 (D, A, B, C, buf_p, corr_p, 12, 0xe8c7b756);
		OP1 (C, D, A, B, buf_p, corr_p, 17, 0x242070db);
		OP1 (B, C, D, A, buf_p, corr_p, 22, 0xc1bdceee);
		OP1 (A, B, C, D, buf_p, corr_p,  7, 0xf57c0faf);
		OP1 (D, A, B, C, buf_p, corr_p, 12, 0x4787c62a);
		OP1 (C, D, A, B, buf_p, corr_p, 17, 0xa8304613);
		OP1 (B, C, D, A, buf_p, corr_p, 22, 0xfd469501);
		OP1 (A, B, C, D, buf_p, corr_p,  7, 0x698098d8);
		OP1 (D, A, B, C, buf_p, corr_p, 12, 0x8b44f7af);
		OP1 (C, D, A, B, buf_p, corr_p, 17, 0xffff5bb1);
		OP1 (B, C, D, A, buf_p, corr_p, 22, 0x895cd7be);
		OP1 (A, B, C, D, buf_p, corr_p,  7, 0x6b901122);
		OP1 (D, A, B, C, buf_p, corr_p, 12, 0xfd987193);
		OP1 (C, D, A, B, buf_p, corr_p, 17, 0xa679438e);
		OP1 (B, C, D, A, buf_p, corr_p, 22, 0x49b40821);
		
		/* Round 2. */
		OP234 (FG, A, B, C, D, correct[  1],  5, 0xf61e2562);
		OP234 (FG, D, A, B, C, correct[  6],  9, 0xc040b340);
		OP234 (FG, C, D, A, B, correct[ 11], 14, 0x265e5a51);
		OP234 (FG, B, C, D, A, correct[  0], 20, 0xe9b6c7aa);
		OP234 (FG, A, B, C, D, correct[  5],  5, 0xd62f105d);
		OP234 (FG, D, A, B, C, correct[ 10],  9, 0x02441453);
		OP234 (FG, C, D, A, B, correct[ 15], 14, 0xd8a1e681);
		OP234 (FG, B, C, D, A, correct[  4], 20, 0xe7d3fbc8);
		OP234 (FG, A, B, C, D, correct[  9],  5, 0x21e1cde6);
		OP234 (FG, D, A, B, C, correct[ 14],  9, 0xc33707d6);
		OP234 (FG, C, D, A, B, correct[  3], 14, 0xf4d50d87);
		OP234 (FG, B, C, D, A, correct[  8], 20, 0x455a14ed);
		OP234 (FG, A, B, C, D, correct[ 13],  5, 0xa9e3e905);
		OP234 (FG, D, A, B, C, correct[  2],  9, 0xfcefa3f8);
		OP234 (FG, C, D, A, B, correct[  7], 14, 0x676f02d9);
		OP234 (FG, B, C, D, A, correct[ 12], 20, 0x8d2a4c8a);
		
		/* Round 3. */
		OP234 (FH, A, B, C, D, correct[  5],  4, 0xfffa3942);
		OP234 (FH, D, A, B, C, correct[  8], 11, 0x8771f681);
		OP234 (FH, C, D, A, B, correct[ 11], 16, 0x6d9d6122);
		OP234 (FH, B, C, D, A, correct[ 14], 23, 0xfde5380c);
		OP234 (FH, A, B, C, D, correct[  1],  4, 0xa4beea44);
		OP234 (FH, D, A, B, C, correct[  4], 11, 0x4bdecfa9);
		OP234 (FH, C, D, A, B, correct[  7], 16, 0xf6bb4b60);
		OP234 (FH, B, C, D, A, correct[ 10], 23, 0xbebfbc70);
		OP234 (FH, A, B, C, D, correct[ 13],  4, 0x289b7ec6);
		OP234 (FH, D, A, B, C, correct[  0], 11, 0xeaa127fa);
		OP234 (FH, C, D, A, B, correct[  3], 16, 0xd4ef3085);
		OP234 (FH, B, C, D, A, correct[  6], 23, 0x04881d05);
		OP234 (FH, A, B, C, D, correct[  9],  4, 0xd9d4d039);
		OP234 (FH, D, A, B, C, correct[ 12], 11, 0xe6db99e5);
		OP234 (FH, C, D, A, B, correct[ 15], 16, 0x1fa27cf8);
		OP234 (FH, B, C, D, A, correct[  2], 23, 0xc4ac5665);
		
		/* Round 4. */
		OP234 (FI, A, B, C, D, correct[  0],  6, 0xf4292244);
		OP234 (FI, D, A, B, C, correct[  7], 10, 0x432aff97);
		OP234 (FI, C, D, A, B, correct[ 14], 15, 0xab9423a7);
		OP234 (FI, B, C, D, A, correct[  5], 21, 0xfc93a039);
		OP234 (FI, A, B, C, D, correct[ 12],  6, 0x655b59c3);
		OP234 (FI, D, A, B, C, correct[  3], 10, 0x8f0ccc92);
		OP234 (FI, C, D, A, B, correct[ 10], 15, 0xffeff47d);
		OP234 (FI, B, C, D, A, correct[  1], 21, 0x85845dd1);
		OP234 (FI, A, B, C, D, correct[  8],  6, 0x6fa87e4f);
		OP234 (FI, D, A, B, C, correct[ 15], 10, 0xfe2ce6e0);
		OP234 (FI, C, D, A, B, correct[  6], 15, 0xa3014314);
		OP234 (FI, B, C, D, A, correct[ 13], 21, 0x4e0811a1);
		OP234 (FI, A, B, C, D, correct[  4],  6, 0xf7537e82);
		OP234 (FI, D, A, B, C, correct[ 11], 10, 0xbd3af235);
		OP234 (FI, C, D, A, B, correct[  2], 15, 0x2ad7d2bb);
		OP234 (FI, B, C, D, A, correct[  9], 21, 0xeb86d391);
		
		/* Add the starting values of the context. */
		A += A_save;
		B += B_save;
		C += C_save;
		D += D_save;
	}

	/* Put checksum in context given as argument. */
	md5_p->md_A = A;
	md5_p->md_B = B;
	md5_p->md_C = C;
	md5_p->md_D = D;
}

/*
 * md5_get_result
 *
 * DESCRIPTION:
 *
 * Copy the resulting MD5 signature from MD5_P into the first 16 bytes
 * (MD5_SIZE) of the result buffer.
 *
 * RETURNS:
 *
 * None.
 *
 * ARGUMENTS:
 *
 * md5_p - Pointer to MD5 structure from which we are getting the result.
 *
 * result - A 16 byte buffer that will contain the MD5 signature.
 */
static void	md5_get_result(const md5_t *md5_p, void *result)
{
	md5_uint32	hold;
	void		*res_p = result;
	
	hold = SWAP(md5_p->md_A);
	memcpy(res_p, &hold, sizeof(md5_uint32));

⌨️ 快捷键说明

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