xref: /openbsd-src/gnu/usr.bin/cvs/lib/md5.c (revision 780d15dfff9934c79e6717020f46114c9b7d7d04)
1 /*
2  * This code implements the MD5 message-digest algorithm.
3  * The algorithm is due to Ron Rivest.  This code was
4  * written by Colin Plumb in 1993, no copyright is claimed.
5  * This code is in the public domain; do with it what you wish.
6  *
7  * Equivalent code is available from RSA Data Security, Inc.
8  * This code has been tested against that, and is equivalent,
9  * except that you don't need to include two pages of legalese
10  * with every copy.
11  *
12  * To compute the message digest of a chunk of bytes, declare an
13  * MD5Context structure, pass it to MD5Init, call MD5Update as
14  * needed on buffers full of bytes, and then call MD5Final, which
15  * will fill a supplied 16-byte array with the digest.
16  */
17 
18 /* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
19    not require an integer type which is exactly 32 bits.  This work
20    draws on the changes for the same purpose by Tatu Ylonen
21    <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
22    that code, there is no copyright issue.  I hereby disclaim
23    copyright in any changes I have made; this code remains in the
24    public domain.  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #if HAVE_STRING_H || STDC_HEADERS
31 #include <string.h>	/* for memcpy() */
32 #endif
33 
34 /* Add prototype support.  */
35 #ifndef PROTO
36 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
37 #define PROTO(ARGS) ARGS
38 #else
39 #define PROTO(ARGS) ()
40 #endif
41 #endif
42 
43 #include "md5.h"
44 
45 /* Little-endian byte-swapping routines.  Note that these do not
46    depend on the size of datatypes such as uint32, nor do they require
47    us to detect the endianness of the machine we are running on.  It
48    is possible they should be macros for speed, but I would be
49    surprised if they were a performance bottleneck for MD5.  */
50 
51 static uint32
52 getu32 (addr)
53      const unsigned char *addr;
54 {
55 	return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
56 		| addr[1]) << 8 | addr[0];
57 }
58 
59 static void
60 putu32 (data, addr)
61      uint32 data;
62      unsigned char *addr;
63 {
64 	addr[0] = (unsigned char)data;
65 	addr[1] = (unsigned char)(data >> 8);
66 	addr[2] = (unsigned char)(data >> 16);
67 	addr[3] = (unsigned char)(data >> 24);
68 }
69 
70 /*
71  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
72  * initialization constants.
73  */
74 void
75 MD5Init(ctx)
76      struct MD5Context *ctx;
77 {
78 	ctx->buf[0] = 0x67452301;
79 	ctx->buf[1] = 0xefcdab89;
80 	ctx->buf[2] = 0x98badcfe;
81 	ctx->buf[3] = 0x10325476;
82 
83 	ctx->bits[0] = 0;
84 	ctx->bits[1] = 0;
85 }
86 
87 /*
88  * Update context to reflect the concatenation of another buffer full
89  * of bytes.
90  */
91 void
92 MD5Update(ctx, buf, len)
93      struct MD5Context *ctx;
94      unsigned char const *buf;
95      unsigned len;
96 {
97 	uint32 t;
98 
99 	/* Update bitcount */
100 
101 	t = ctx->bits[0];
102 	if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
103 		ctx->bits[1]++;	/* Carry from low to high */
104 	ctx->bits[1] += len >> 29;
105 
106 	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
107 
108 	/* Handle any leading odd-sized chunks */
109 
110 	if ( t ) {
111 		unsigned char *p = ctx->in + t;
112 
113 		t = 64-t;
114 		if (len < t) {
115 			memcpy(p, buf, len);
116 			return;
117 		}
118 		memcpy(p, buf, t);
119 		MD5Transform(ctx->buf, ctx->in);
120 		buf += t;
121 		len -= t;
122 	}
123 
124 	/* Process data in 64-byte chunks */
125 
126 	while (len >= 64) {
127 		memcpy(ctx->in, buf, 64);
128 		MD5Transform(ctx->buf, ctx->in);
129 		buf += 64;
130 		len -= 64;
131 	}
132 
133 	/* Handle any remaining bytes of data. */
134 
135 	memcpy(ctx->in, buf, len);
136 }
137 
138 /*
139  * Final wrapup - pad to 64-byte boundary with the bit pattern
140  * 1 0* (64-bit count of bits processed, MSB-first)
141  */
142 void
143 MD5Final(digest, ctx)
144      unsigned char digest[16];
145      struct MD5Context *ctx;
146 {
147 	unsigned count;
148 	unsigned char *p;
149 
150 	/* Compute number of bytes mod 64 */
151 	count = (ctx->bits[0] >> 3) & 0x3F;
152 
153 	/* Set the first char of padding to 0x80.  This is safe since there is
154 	   always at least one byte free */
155 	p = ctx->in + count;
156 	*p++ = 0x80;
157 
158 	/* Bytes of padding needed to make 64 bytes */
159 	count = 64 - 1 - count;
160 
161 	/* Pad out to 56 mod 64 */
162 	if (count < 8) {
163 		/* Two lots of padding:  Pad the first block to 64 bytes */
164 		memset(p, 0, count);
165 		MD5Transform(ctx->buf, ctx->in);
166 
167 		/* Now fill the next block with 56 bytes */
168 		memset(ctx->in, 0, 56);
169 	} else {
170 		/* Pad block to 56 bytes */
171 		memset(p, 0, count-8);
172 	}
173 
174 	/* Append length in bits and transform */
175 	putu32(ctx->bits[0], ctx->in + 56);
176 	putu32(ctx->bits[1], ctx->in + 60);
177 
178 	MD5Transform(ctx->buf, ctx->in);
179 	putu32(ctx->buf[0], digest);
180 	putu32(ctx->buf[1], digest + 4);
181 	putu32(ctx->buf[2], digest + 8);
182 	putu32(ctx->buf[3], digest + 12);
183 	memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
184 }
185 
186 #ifndef ASM_MD5
187 
188 /* The four core functions - F1 is optimized somewhat */
189 
190 /* #define F1(x, y, z) (x & y | ~x & z) */
191 #define F1(x, y, z) (z ^ (x & (y ^ z)))
192 #define F2(x, y, z) F1(z, x, y)
193 #define F3(x, y, z) (x ^ y ^ z)
194 #define F4(x, y, z) (y ^ (x | ~z))
195 
196 /* This is the central step in the MD5 algorithm. */
197 #define MD5STEP(f, w, x, y, z, data, s) \
198 	( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
199 
200 /*
201  * The core of the MD5 algorithm, this alters an existing MD5 hash to
202  * reflect the addition of 16 longwords of new data.  MD5Update blocks
203  * the data and converts bytes into longwords for this routine.
204  */
205 void
206 MD5Transform(buf, inraw)
207      uint32 buf[4];
208      const unsigned char inraw[64];
209 {
210 	register uint32 a, b, c, d;
211 	uint32 in[16];
212 	int i;
213 
214 	for (i = 0; i < 16; ++i)
215 		in[i] = getu32 (inraw + 4 * i);
216 
217 	a = buf[0];
218 	b = buf[1];
219 	c = buf[2];
220 	d = buf[3];
221 
222 	MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
223 	MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
224 	MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
225 	MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
226 	MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
227 	MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
228 	MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
229 	MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
230 	MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
231 	MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
232 	MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
233 	MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
234 	MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
235 	MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
236 	MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
237 	MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
238 
239 	MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
240 	MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
241 	MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
242 	MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
243 	MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
244 	MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
245 	MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
246 	MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
247 	MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
248 	MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
249 	MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
250 	MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
251 	MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
252 	MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
253 	MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
254 	MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
255 
256 	MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
257 	MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
258 	MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
259 	MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
260 	MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
261 	MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
262 	MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
263 	MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
264 	MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
265 	MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
266 	MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
267 	MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
268 	MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
269 	MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
270 	MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
271 	MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
272 
273 	MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
274 	MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
275 	MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
276 	MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
277 	MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
278 	MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
279 	MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
280 	MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
281 	MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
282 	MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
283 	MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
284 	MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
285 	MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
286 	MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
287 	MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
288 	MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
289 
290 	buf[0] += a;
291 	buf[1] += b;
292 	buf[2] += c;
293 	buf[3] += d;
294 }
295 #endif
296 
297 #ifdef TEST
298 /* Simple test program.  Can use it to manually run the tests from
299    RFC1321 for example.  */
300 #include <stdio.h>
301 
302 int
303 main (int argc, char **argv)
304 {
305 	struct MD5Context context;
306 	unsigned char checksum[16];
307 	int i;
308 	int j;
309 
310 	if (argc < 2)
311 	{
312 		fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
313 		exit (1);
314 	}
315 	for (j = 1; j < argc; ++j)
316 	{
317 		printf ("MD5 (\"%s\") = ", argv[j]);
318 		MD5Init (&context);
319 		MD5Update (&context, argv[j], strlen (argv[j]));
320 		MD5Final (checksum, &context);
321 		for (i = 0; i < 16; i++)
322 		{
323 			printf ("%02x", (unsigned int) checksum[i]);
324 		}
325 		printf ("\n");
326 	}
327 	return 0;
328 }
329 #endif /* TEST */
330