Browse code

use new MD5 implementation

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1360 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2005/03/01 09:18:49
Showing 5 changed files
... ...
@@ -1,3 +1,8 @@
1
+Tue Mar  1 01:13:20 CET 2005 (tk)
2
+---------------------------------
3
+  * libclamav: use new MD5 implementation (thanks to Solar Designer
4
+	       <solar*openwall.com>)
5
+
1 6
 Sun Feb 27 02:26:42 CET 2005 (tk)
2 7
 ---------------------------------
3 8
   * libclamav: improve metadata scanner
... ...
@@ -203,7 +203,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
203 203
  	char *buffer, *buff, *endbl, *pt;
204 204
 	int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN;
205 205
 	unsigned long int *partoff, offset = 0;
206
-	struct MD5Context ctx;
206
+	MD5_CTX ctx;
207 207
 	unsigned char digest[16];
208 208
 	struct cli_md5_node *md5_node;
209 209
 
... ...
@@ -234,7 +234,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
234 234
     }
235 235
 
236 236
     if(root->md5_hlist)
237
-	MD5Init(&ctx);
237
+	MD5_Init(&ctx);
238 238
 
239 239
 
240 240
     buff = buffer;
... ...
@@ -274,7 +274,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
274 274
         length = buffsize;
275 275
 
276 276
 	if(root->md5_hlist)
277
-	    MD5Update(&ctx, buff, bytes);
277
+	    MD5_Update(&ctx, buff, bytes);
278 278
     }
279 279
 
280 280
     free(buffer);
... ...
@@ -282,7 +282,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
282 282
     free(partoff);
283 283
 
284 284
     if(root->md5_hlist) {
285
-	MD5Final(digest, &ctx);
285
+	MD5_Final(digest, &ctx);
286 286
 
287 287
 	if(cli_debug_flag) {
288 288
 		char md5str[33];
... ...
@@ -1,236 +1,273 @@
1 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.
2
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
3
+ * Inc. MD5 Message-Digest Algorithm.
6 4
  *
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.
5
+ * Written by Solar Designer <solar at openwall.com> in 2001, and placed
6
+ * in the public domain.  There's absolutely no warranty.
11 7
  *
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.
8
+ * This differs from Colin Plumb's older public domain implementation in
9
+ * that no 32-bit integer data type is required, there's no compile-time
10
+ * endianness configuration, and the function prototypes match OpenSSL's.
11
+ * The primary goals are portability and ease of use.
16 12
  *
13
+ * This implementation is meant to be fast, but not as fast as possible.
14
+ * Some known optimizations are not included to reduce source code size
15
+ * and avoid compile-time configuration.
17 16
  */
18 17
 
19 18
 #if HAVE_CONFIG_H
20 19
 #include "clamav-config.h"
21 20
 #endif
22 21
 
23
-#include <string.h>		/* for memcpy() */
24
-#include <sys/types.h>		/* for stupid systems */
25
-#include <netinet/in.h>		/* for ntohl() */
26
-
22
+#include <string.h>
27 23
 #include "md5.h"
28 24
 
29
-#if WORDS_BIGENDIAN
30
-void
31
-byteSwap(uint32_t *buf, unsigned words)
32
-{
33
-	md5byte *p = (md5byte *)buf;
25
+/*
26
+ * The basic MD5 functions.
27
+ *
28
+ * F is optimized compared to its RFC 1321 definition just like in Colin
29
+ * Plumb's implementation.
30
+ */
31
+#define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
32
+#define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
33
+#define H(x, y, z)			((x) ^ (y) ^ (z))
34
+#define I(x, y, z)			((y) ^ ((x) | ~(z)))
34 35
 
35
-	do {
36
-		*buf++ = (uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 |
37
-			((unsigned)p[1] << 8 | p[0]);
38
-		p += 4;
39
-	} while (--words);
40
-}
36
+/*
37
+ * The MD5 transformation for all four rounds.
38
+ */
39
+#define STEP(f, a, b, c, d, x, t, s) \
40
+	(a) += f((b), (c), (d)) + (x) + (t); \
41
+	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
42
+	(a) += (b);
43
+
44
+/*
45
+ * SET reads 4 input bytes in little-endian byte order and stores them
46
+ * in a properly aligned word in host byte order.
47
+ *
48
+ * The check for little-endian architectures which tolerate unaligned
49
+ * memory accesses is just an optimization.  Nothing will break if it
50
+ * doesn't work.
51
+ */
52
+#if defined(__i386__) || defined(__vax__)
53
+#define SET(n) \
54
+	(*(MD5_u32plus *)&ptr[(n) * 4])
55
+#define GET(n) \
56
+	SET(n)
41 57
 #else
42
-#define byteSwap(buf,words)
58
+#define SET(n) \
59
+	(ctx->block[(n)] = \
60
+	(MD5_u32plus)ptr[(n) * 4] | \
61
+	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
62
+	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
63
+	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
64
+#define GET(n) \
65
+	(ctx->block[(n)])
43 66
 #endif
44 67
 
45 68
 /*
46
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
47
- * initialization constants.
69
+ * This processes one or more 64-byte data blocks, but does NOT update
70
+ * the bit counters.  There're no alignment requirements.
48 71
  */
49
-void
50
-MD5Init(struct MD5Context *ctx)
72
+static void *body(MD5_CTX *ctx, void *data, unsigned long size)
51 73
 {
52
-	ctx->buf[0] = 0x67452301;
53
-	ctx->buf[1] = 0xefcdab89;
54
-	ctx->buf[2] = 0x98badcfe;
55
-	ctx->buf[3] = 0x10325476;
74
+	unsigned char *ptr;
75
+	MD5_u32plus a, b, c, d;
76
+	MD5_u32plus saved_a, saved_b, saved_c, saved_d;
77
+
78
+	ptr = data;
79
+
80
+	a = ctx->a;
81
+	b = ctx->b;
82
+	c = ctx->c;
83
+	d = ctx->d;
84
+
85
+	do {
86
+		saved_a = a;
87
+		saved_b = b;
88
+		saved_c = c;
89
+		saved_d = d;
90
+
91
+/* Round 1 */
92
+		STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
93
+		STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
94
+		STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
95
+		STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
96
+		STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
97
+		STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
98
+		STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
99
+		STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
100
+		STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
101
+		STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
102
+		STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
103
+		STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
104
+		STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
105
+		STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
106
+		STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
107
+		STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
108
+
109
+/* Round 2 */
110
+		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
111
+		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
112
+		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
113
+		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
114
+		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
115
+		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
116
+		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
117
+		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
118
+		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
119
+		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
120
+		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
121
+		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
122
+		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
123
+		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
124
+		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
125
+		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
126
+
127
+/* Round 3 */
128
+		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
129
+		STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
130
+		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
131
+		STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
132
+		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
133
+		STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
134
+		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
135
+		STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
136
+		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
137
+		STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
138
+		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
139
+		STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
140
+		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
141
+		STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
142
+		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
143
+		STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
144
+
145
+/* Round 4 */
146
+		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
147
+		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
148
+		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
149
+		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
150
+		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
151
+		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
152
+		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
153
+		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
154
+		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
155
+		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
156
+		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
157
+		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
158
+		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
159
+		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
160
+		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
161
+		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
56 162
 
57
-	ctx->bytes[0] = 0;
58
-	ctx->bytes[1] = 0;
163
+		a += saved_a;
164
+		b += saved_b;
165
+		c += saved_c;
166
+		d += saved_d;
167
+
168
+		ptr += 64;
169
+	} while (size -= 64);
170
+
171
+	ctx->a = a;
172
+	ctx->b = b;
173
+	ctx->c = c;
174
+	ctx->d = d;
175
+
176
+	return ptr;
59 177
 }
60 178
 
61
-/*
62
- * Update context to reflect the concatenation of another buffer full
63
- * of bytes.
64
- */
65
-void
66
-MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
179
+void MD5_Init(MD5_CTX *ctx)
67 180
 {
68
-	uint32_t t;
181
+	ctx->a = 0x67452301;
182
+	ctx->b = 0xefcdab89;
183
+	ctx->c = 0x98badcfe;
184
+	ctx->d = 0x10325476;
185
+
186
+	ctx->lo = 0;
187
+	ctx->hi = 0;
188
+}
189
+
190
+void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
191
+{
192
+	MD5_u32plus saved_lo;
193
+	unsigned long used, free;
194
+
195
+	saved_lo = ctx->lo;
196
+	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
197
+		ctx->hi++;
198
+	ctx->hi += size >> 29;
69 199
 
70
-	/* Update byte count */
200
+	used = saved_lo & 0x3f;
71 201
 
72
-	t = ctx->bytes[0];
73
-	if ((ctx->bytes[0] = t + len) < t)
74
-		ctx->bytes[1]++;	/* Carry from low to high */
202
+	if (used) {
203
+		free = 64 - used;
75 204
 
76
-	t = 64 - (t & 0x3f);	/* Space available in ctx->in (at least 1) */
77
-	if (t > len) {
78
-		memcpy((md5byte *)ctx->in + 64 - t, buf, len);
79
-		return;
205
+		if (size < free) {
206
+			memcpy(&ctx->buffer[used], data, size);
207
+			return;
208
+		}
209
+
210
+		memcpy(&ctx->buffer[used], data, free);
211
+		data = (unsigned char *)data + free;
212
+		size -= free;
213
+		body(ctx, ctx->buffer, 64);
80 214
 	}
81
-	/* First chunk is an odd size */
82
-	memcpy((md5byte *)ctx->in + 64 - t, buf, t);
83
-	byteSwap(ctx->in, 16);
84
-	MD5Transform(ctx->buf, ctx->in);
85
-	buf += t;
86
-	len -= t;
87
-
88
-	/* Process data in 64-byte chunks */
89
-	while (len >= 64) {
90
-		memcpy(ctx->in, buf, 64);
91
-		byteSwap(ctx->in, 16);
92
-		MD5Transform(ctx->buf, ctx->in);
93
-		buf += 64;
94
-		len -= 64;
215
+
216
+	if (size >= 64) {
217
+		data = body(ctx, data, size & ~(unsigned long)0x3f);
218
+		size &= 0x3f;
95 219
 	}
96 220
 
97
-	/* Handle any remaining bytes of data. */
98
-	memcpy(ctx->in, buf, len);
221
+	memcpy(ctx->buffer, data, size);
99 222
 }
100 223
 
101
-/*
102
- * Final wrapup - pad to 64-byte boundary with the bit pattern 
103
- * 1 0* (64-bit count of bits processed, MSB-first)
104
- */
105
-void
106
-MD5Final(md5byte *digest, struct MD5Context *ctx)
224
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
107 225
 {
108
-	int count = ctx->bytes[0] & 0x3f;	/* Number of bytes in ctx->in */
109
-	md5byte *p = (md5byte *)ctx->in + count;
226
+	unsigned long used, free;
110 227
 
111
-	/* Set the first char of padding to 0x80.  There is always room. */
112
-	*p++ = 0x80;
228
+	used = ctx->lo & 0x3f;
113 229
 
114
-	/* Bytes of padding needed to make 56 bytes (-8..55) */
115
-	count = 56 - 1 - count;
230
+	ctx->buffer[used++] = 0x80;
116 231
 
117
-	if (count < 0) {	/* Padding forces an extra block */
118
-		memset(p, 0, count + 8);
119
-		byteSwap(ctx->in, 16);
120
-		MD5Transform(ctx->buf, ctx->in);
121
-		p = (md5byte *)ctx->in;
122
-		count = 56;
123
-	}
124
-	memset(p, 0, count);
125
-	byteSwap(ctx->in, 14);
232
+	free = 64 - used;
126 233
 
127
-	/* Append length in bits and transform */
128
-	ctx->in[14] = ctx->bytes[0] << 3;
129
-	ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
130
-	MD5Transform(ctx->buf, ctx->in);
234
+	if (free < 8) {
235
+		memset(&ctx->buffer[used], 0, free);
236
+		body(ctx, ctx->buffer, 64);
237
+		used = 0;
238
+		free = 64;
239
+	}
131 240
 
132
-	byteSwap(ctx->buf, 4);
133
-	memcpy(digest, ctx->buf, 16);
134
-	memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
135
-}
241
+	memset(&ctx->buffer[used], 0, free - 8);
136 242
 
137
-/* The four core functions - F1 is optimized somewhat */
243
+	ctx->lo <<= 3;
244
+	ctx->buffer[56] = ctx->lo;
245
+	ctx->buffer[57] = ctx->lo >> 8;
246
+	ctx->buffer[58] = ctx->lo >> 16;
247
+	ctx->buffer[59] = ctx->lo >> 24;
248
+	ctx->buffer[60] = ctx->hi;
249
+	ctx->buffer[61] = ctx->hi >> 8;
250
+	ctx->buffer[62] = ctx->hi >> 16;
251
+	ctx->buffer[63] = ctx->hi >> 24;
138 252
 
139
-/* #define F1(x, y, z) (x & y | ~x & z) */
140
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
141
-#define F2(x, y, z) F1(z, x, y)
142
-#define F3(x, y, z) (x ^ y ^ z)
143
-#define F4(x, y, z) (y ^ (x | ~z))
253
+	body(ctx, ctx->buffer, 64);
144 254
 
145
-/* This is the central step in the MD5 algorithm. */
146
-#define MD5STEP(f,w,x,y,z,in,s) \
147
-	 (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
255
+	result[0] = ctx->a;
256
+	result[1] = ctx->a >> 8;
257
+	result[2] = ctx->a >> 16;
258
+	result[3] = ctx->a >> 24;
259
+	result[4] = ctx->b;
260
+	result[5] = ctx->b >> 8;
261
+	result[6] = ctx->b >> 16;
262
+	result[7] = ctx->b >> 24;
263
+	result[8] = ctx->c;
264
+	result[9] = ctx->c >> 8;
265
+	result[10] = ctx->c >> 16;
266
+	result[11] = ctx->c >> 24;
267
+	result[12] = ctx->d;
268
+	result[13] = ctx->d >> 8;
269
+	result[14] = ctx->d >> 16;
270
+	result[15] = ctx->d >> 24;
148 271
 
149
-/*
150
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
151
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
152
- * the data and converts bytes into longwords for this routine.
153
- */
154
-void
155
-MD5Transform(uint32_t buf[4], uint32_t const in[16])
156
-{
157
-	uint32_t a, b, c, d;
158
-
159
-	a = buf[0];
160
-	b = buf[1];
161
-	c = buf[2];
162
-	d = buf[3];
163
-
164
-	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
165
-	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
166
-	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
167
-	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
168
-	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
169
-	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
170
-	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
171
-	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
172
-	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
173
-	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
174
-	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
175
-	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
176
-	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
177
-	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
178
-	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
179
-	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
180
-
181
-	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
182
-	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
183
-	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
184
-	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
185
-	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
186
-	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
187
-	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
188
-	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
189
-	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
190
-	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
191
-	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
192
-	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
193
-	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
194
-	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
195
-	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
196
-	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
197
-
198
-	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
199
-	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
200
-	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
201
-	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
202
-	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
203
-	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
204
-	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
205
-	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
206
-	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
207
-	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
208
-	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
209
-	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
210
-	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
211
-	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
212
-	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
213
-	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
214
-
215
-	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
216
-	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
217
-	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
218
-	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
219
-	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
220
-	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
221
-	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
222
-	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
223
-	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
224
-	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
225
-	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
226
-	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
227
-	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
228
-	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
229
-	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
230
-	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
231
-
232
-	buf[0] += a;
233
-	buf[1] += b;
234
-	buf[2] += c;
235
-	buf[3] += d;
272
+	memset(ctx, 0, sizeof(*ctx));
236 273
 }
... ...
@@ -1,37 +1,26 @@
1 1
 /*
2
- * This is the header file for 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.
2
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
3
+ * Inc. MD5 Message-Digest Algorithm.
16 4
  *
5
+ * Written by Solar Designer <solar at openwall.com> in 2001, and placed
6
+ * in the public domain.  See md5.c for more information.
17 7
  */
18 8
 
19 9
 #ifndef __MD5_H
20 10
 #define __MD5_H
21 11
 
22
-#define md5byte unsigned char
23
-
24
-#include "cltypes.h"
12
+/* Any 32-bit or wider unsigned integer data type will do */
13
+typedef unsigned long MD5_u32plus;
25 14
 
26
-struct MD5Context {
27
-	uint32_t buf[4];
28
-	uint32_t bytes[2];
29
-	uint32_t in[16];
30
-};
15
+typedef struct {
16
+	MD5_u32plus lo, hi;
17
+	MD5_u32plus a, b, c, d;
18
+	unsigned char buffer[64];
19
+	MD5_u32plus block[16];
20
+} MD5_CTX;
31 21
 
32
-void MD5Init(struct MD5Context *context);
33
-void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
34
-void MD5Final(unsigned char *digest, struct MD5Context *context);
35
-void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
22
+extern void MD5_Init(MD5_CTX *ctx);
23
+extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
24
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
36 25
 
37 26
 #endif
... ...
@@ -196,17 +196,17 @@ char *cli_md5stream(FILE *fs, unsigned char *digcpy)
196 196
 {
197 197
 	unsigned char digest[16];
198 198
 	char buff[FILEBUFF];
199
-	struct MD5Context ctx;
199
+	MD5_CTX ctx;
200 200
 	char *md5str, *pt;
201 201
 	int i, bytes;
202 202
 
203 203
 
204
-    MD5Init(&ctx);
204
+    MD5_Init(&ctx);
205 205
 
206 206
     while((bytes = fread(buff, 1, FILEBUFF, fs)))
207
-	MD5Update(&ctx, buff, bytes);
207
+	MD5_Update(&ctx, buff, bytes);
208 208
 
209
-    MD5Final(digest, &ctx);
209
+    MD5_Final(digest, &ctx);
210 210
 
211 211
     if(!(md5str = (char *) cli_calloc(32 + 1, sizeof(char))))
212 212
 	return NULL;
... ...
@@ -244,13 +244,13 @@ static char *cli_md5buff(const char *buffer, unsigned int len)
244 244
 {
245 245
 	unsigned char digest[16];
246 246
 	char *md5str, *pt;
247
-	struct MD5Context ctx;
247
+	MD5_CTX ctx;
248 248
 	int i;
249 249
 
250 250
 
251
-    MD5Init(&ctx);
252
-    MD5Update(&ctx, buffer, len);
253
-    MD5Final(digest, &ctx);
251
+    MD5_Init(&ctx);
252
+    MD5_Update(&ctx, (unsigned char *) buffer, len);
253
+    MD5_Final(digest, &ctx);
254 254
     memcpy(oldmd5buff, digest, 16);
255 255
 
256 256
     if(!(md5str = (char *) cli_calloc(32 + 1, sizeof(char))))