Browse code

replace current MD5 implementation with another one

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

Tomasz Kojm authored on 2004/09/01 23:14:21
Showing 8 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Sep  1 16:11:40 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav: replace current MD5 implementation with another one
4
+
1 5
 Wed Sep  1 03:32:28 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * libclamav/cvd.c: display warning if loaded database is older than 7 days
... ...
@@ -288,7 +288,7 @@ int cli_cvdverify(FILE *fd, struct cl_cvd *cvdpt)
288 288
     if(cvdpt)
289 289
 	memcpy(cvdpt, cvd, sizeof(struct cl_cvd));
290 290
 
291
-    md5 = cli_md5stream(fd);
291
+    md5 = cli_md5stream(fd, NULL);
292 292
     cli_dbgmsg("MD5(.tar.gz) = %s\n", md5);
293 293
 
294 294
     if(strncmp(md5, cvd->md5, 32)) {
... ...
@@ -80,8 +80,8 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
80 80
  	char *buffer, *buff, *endbl, *pt;
81 81
 	int bytes, buffsize, length, ret, *partcnt, type = CL_CLEAN;
82 82
 	unsigned long int *partoff, offset = 0;
83
-	struct md5_ctx ctx;
84
-        unsigned char md5buff[16];
83
+	struct MD5Context ctx;
84
+	unsigned char digest[16];
85 85
 	struct cli_md5_node *md5_node;
86 86
 
87 87
 
... ...
@@ -111,7 +111,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
111 111
     }
112 112
 
113 113
     if(root->md5_hlist)
114
-	md5_init_ctx (&ctx);
114
+	MD5Init(&ctx);
115 115
 
116 116
     buff = buffer;
117 117
     buff += root->maxpatlen; /* pointer to read data block */
... ...
@@ -119,7 +119,7 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
119 119
 						* length of root->maxpatlen
120 120
 						*/
121 121
 
122
-    pt= buff;
122
+    pt = buff;
123 123
     length = SCANBUFF;
124 124
     while((bytes = read(desc, buff, SCANBUFF)) > 0) {
125 125
 
... ...
@@ -149,25 +149,8 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
149 149
         pt = buffer;
150 150
         length = buffsize;
151 151
 
152
-	/* compute MD5 */
153
-
154
-	if(root->md5_hlist) {
155
-	    if(bytes % 64 == 0) {
156
-		md5_process_block(buff, bytes, &ctx);
157
-	    } else {
158
-		    int block = bytes;
159
-		    char *mpt = buff;
160
-
161
-		while(block >= MD5_BLOCKSIZE) {
162
-		    md5_process_block(mpt, MD5_BLOCKSIZE, &ctx);
163
-		    mpt += MD5_BLOCKSIZE;
164
-		    block -= MD5_BLOCKSIZE;
165
-		}
166
-
167
-		if(block)
168
-		    md5_process_bytes(mpt, block, &ctx);
169
-	    }
170
-	}
152
+	if(root->md5_hlist)
153
+	    MD5Update(&ctx, buff, bytes);
171 154
     }
172 155
 
173 156
     free(buffer);
... ...
@@ -175,9 +158,9 @@ int cli_scandesc(int desc, const char **virname, long int *scanned, const struct
175 175
     free(partoff);
176 176
 
177 177
     if(root->md5_hlist) {
178
-	md5_finish_ctx(&ctx, &md5buff);
178
+	MD5Final(digest, &ctx);
179 179
 
180
-	if((md5_node = cli_vermd5(md5buff, root))) {
180
+	if((md5_node = cli_vermd5(digest, root))) {
181 181
 		struct stat sb;
182 182
 
183 183
 	    if(fstat(desc, &sb))
... ...
@@ -1,434 +1,236 @@
1
-/* Functions to compute MD5 message digest of files or memory blocks.
2
-   according to the definition of MD5 in RFC 1321 from April 1992.
3
-   Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
4
-   This file is part of the GNU C Library.
5
-
6
-   The GNU C Library is free software; you can redistribute it and/or
7
-   modify it under the terms of the GNU Library General Public License as
8
-   published by the Free Software Foundation; either version 2 of the
9
-   License, or (at your option) any later version.
10
-
11
-   The GNU C Library is distributed in the hope that it will be useful,
12
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
-   Library General Public License for more details.
15
-
16
-   You should have received a copy of the GNU Library General Public
17
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
18
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
-   Boston, MA 02111-1307, USA.  */
20
-
21
-/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
22
-
23
-#ifdef HAVE_CONFIG_H
24
-# include <clamav-config.h>
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
+
19
+#if HAVE_CONFIG_H
20
+#include "clamav-config.h"
25 21
 #endif
26 22
 
27
-#include <sys/types.h>
28
-
29
-#if STDC_HEADERS || defined _LIBC
30
-# include <stdlib.h>
31
-# include <string.h>
32
-#else
33
-# ifndef HAVE_MEMCPY
34
-#  define memcpy(d, s, n) bcopy ((s), (d), (n))
35
-# endif
36
-#endif
23
+#include <string.h>		/* for memcpy() */
24
+#include <sys/types.h>		/* for stupid systems */
25
+#include <netinet/in.h>		/* for ntohl() */
37 26
 
38 27
 #include "md5.h"
39 28
 
40
-/* Not needed, since endianess is already taken care of by configure
41
-#ifdef _LIBC
42
-# include <endian.h>
43
-# if __BYTE_ORDER == __BIG_ENDIAN
44
-#  define WORDS_BIGENDIAN 1
45
-# endif
46
-#endif
47
-*/
48
-
49 29
 #if WORDS_BIGENDIAN
50
-# define SWAP(n)							\
51
-    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
52
-#else
53
-# define SWAP(n) (n)
54
-#endif
55
-
56
-
57
-/* This array contains the bytes used to pad the buffer to the next
58
-   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
59
-static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
60
-
61
-
62
-/* Initialize structure containing state of computation.
63
-   (RFC 1321, 3.3: Step 3)  */
64 30
 void
65
-md5_init_ctx (ctx)
66
-     struct md5_ctx *ctx;
67
-{
68
-  ctx->A = 0x67452301;
69
-  ctx->B = 0xefcdab89;
70
-  ctx->C = 0x98badcfe;
71
-  ctx->D = 0x10325476;
72
-
73
-  ctx->total[0] = ctx->total[1] = 0;
74
-  ctx->buflen = 0;
75
-}
76
-
77
-/* Put result from CTX in first 16 bytes following RESBUF.  The result
78
-   must be in little endian byte order.
79
-
80
-   IMPORTANT: On some systems it is required that RESBUF is correctly
81
-   aligned for a 32 bits value.  */
82
-void *
83
-md5_read_ctx (ctx, resbuf)
84
-     const struct md5_ctx *ctx;
85
-     void *resbuf;
31
+byteSwap(uint32_t *buf, unsigned words)
86 32
 {
87
-  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
88
-  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
89
-  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
90
-  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
33
+	md5byte *p = (md5byte *)buf;
91 34
 
92
-  return resbuf;
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);
93 40
 }
41
+#else
42
+#define byteSwap(buf,words)
43
+#endif
94 44
 
95
-/* Process the remaining bytes in the internal buffer and the usual
96
-   prolog according to the standard and write the result to RESBUF.
97
-
98
-   IMPORTANT: On some systems it is required that RESBUF is correctly
99
-   aligned for a 32 bits value.  */
100
-void *
101
-md5_finish_ctx (ctx, resbuf)
102
-     struct md5_ctx *ctx;
103
-     void *resbuf;
45
+/*
46
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
47
+ * initialization constants.
48
+ */
49
+void
50
+MD5Init(struct MD5Context *ctx)
104 51
 {
105
-  /* Take yet unprocessed bytes into account.  */
106
-  md5_uint32 bytes = ctx->buflen;
107
-  size_t pad;
108
-
109
-  /* Now count remaining bytes.  */
110
-  ctx->total[0] += bytes;
111
-  if (ctx->total[0] < bytes)
112
-    ++ctx->total[1];
113
-
114
-  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
115
-  memcpy (&ctx->buffer[bytes], fillbuf, pad);
52
+	ctx->buf[0] = 0x67452301;
53
+	ctx->buf[1] = 0xefcdab89;
54
+	ctx->buf[2] = 0x98badcfe;
55
+	ctx->buf[3] = 0x10325476;
116 56
 
117
-  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
118
-  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
119
-  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
120
-							(ctx->total[0] >> 29));
121
-
122
-  /* Process last bytes.  */
123
-  md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
124
-
125
-  return md5_read_ctx (ctx, resbuf);
57
+	ctx->bytes[0] = 0;
58
+	ctx->bytes[1] = 0;
126 59
 }
127 60
 
128
-/* Compute MD5 message digest for bytes read from STREAM.  The
129
-   resulting message digest number will be written into the 16 bytes
130
-   beginning at RESBLOCK.  */
131
-int
132
-md5_stream (stream, resblock)
133
-     FILE *stream;
134
-     void *resblock;
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)
135 67
 {
136
-  /* Important: BLOCKSIZE must be a multiple of 64.  */
137
-#define BLOCKSIZE 4096
138
-  struct md5_ctx ctx;
139
-  char buffer[BLOCKSIZE + 72];
140
-  size_t sum;
68
+	uint32_t t;
141 69
 
142
-  /* Initialize the computation context.  */
143
-  md5_init_ctx (&ctx);
70
+	/* Update byte count */
144 71
 
145
-  /* Iterate over full file contents.  */
146
-  while (1)
147
-    {
148
-      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
149
-	 computation function processes the whole buffer so that with the
150
-	 next round of the loop another block can be read.  */
151
-      size_t n;
152
-      sum = 0;
72
+	t = ctx->bytes[0];
73
+	if ((ctx->bytes[0] = t + len) < t)
74
+		ctx->bytes[1]++;	/* Carry from low to high */
153 75
 
154
-      /* Read block.  Take care for partial reads.  */
155
-      do
156
-	{
157
-	  n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
158
-
159
-	  sum += n;
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;
80
+	}
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;
160 95
 	}
161
-      while (sum < BLOCKSIZE && n != 0);
162
-      if (n == 0 && ferror (stream))
163
-        return 1;
164
-
165
-      /* If end of file is reached, end the loop.  */
166
-      if (n == 0)
167
-	break;
168
-
169
-      /* Process buffer with BLOCKSIZE bytes.  Note that
170
-			BLOCKSIZE % 64 == 0
171
-       */
172
-      md5_process_block (buffer, BLOCKSIZE, &ctx);
173
-    }
174
-
175
-  /* Add the last bytes if necessary.  */
176
-  if (sum > 0)
177
-    md5_process_bytes (buffer, sum, &ctx);
178
-
179
-  /* Construct result in desired memory.  */
180
-  md5_finish_ctx (&ctx, resblock);
181
-  return 0;
182
-}
183
-
184
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
185
-   result is always in little endian byte order, so that a byte-wise
186
-   output yields to the wanted ASCII representation of the message
187
-   digest.  */
188
-void *
189
-md5_buffer (buffer, len, resblock)
190
-     const char *buffer;
191
-     size_t len;
192
-     void *resblock;
193
-{
194
-  struct md5_ctx ctx;
195
-
196
-  /* Initialize the computation context.  */
197
-  md5_init_ctx (&ctx);
198
-
199
-  /* Process whole buffer but last len % 64 bytes.  */
200
-  md5_process_bytes (buffer, len, &ctx);
201 96
 
202
-  /* Put result in desired memory area.  */
203
-  return md5_finish_ctx (&ctx, resblock);
97
+	/* Handle any remaining bytes of data. */
98
+	memcpy(ctx->in, buf, len);
204 99
 }
205 100
 
206
-
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
+ */
207 105
 void
208
-md5_process_bytes (buffer, len, ctx)
209
-     const void *buffer;
210
-     size_t len;
211
-     struct md5_ctx *ctx;
106
+MD5Final(md5byte *digest, struct MD5Context *ctx)
212 107
 {
213
-  /* When we already have some bits in our internal buffer concatenate
214
-     both inputs first.  */
215
-  if (ctx->buflen != 0)
216
-    {
217
-      size_t left_over = ctx->buflen;
218
-      size_t add = 128 - left_over > len ? len : 128 - left_over;
108
+	int count = ctx->bytes[0] & 0x3f;	/* Number of bytes in ctx->in */
109
+	md5byte *p = (md5byte *)ctx->in + count;
219 110
 
220
-      /* Only put full words in the buffer.  */
221
-      add -= add % __alignof__ (md5_uint32);
111
+	/* Set the first char of padding to 0x80.  There is always room. */
112
+	*p++ = 0x80;
222 113
 
223
-      memcpy (&ctx->buffer[left_over], buffer, add);
224
-      ctx->buflen += add;
114
+	/* Bytes of padding needed to make 56 bytes (-8..55) */
115
+	count = 56 - 1 - count;
225 116
 
226
-      if (ctx->buflen > 64)
227
-	{
228
-	  md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
229
-
230
-	  ctx->buflen &= 63;
231
-	  /* The regions in the following copy operation cannot overlap.  */
232
-	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
233
-		  ctx->buflen);
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;
234 123
 	}
124
+	memset(p, 0, count);
125
+	byteSwap(ctx->in, 14);
235 126
 
236
-      buffer = (const char *) buffer + add;
237
-      len -= add;
238
-    }
239
-
240
-  /* Process available complete blocks.  */
241
-  if (len > 64)
242
-    {
243
-      md5_process_block (buffer, len & ~63, ctx);
244
-      buffer = (const char *) buffer + (len & ~63);
245
-      len &= 63;
246
-    }
247
-
248
-  /* Move remaining bytes in internal buffer.  */
249
-  if (len > 0)
250
-    {
251
-      size_t left_over = ctx->buflen;
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);
252 131
 
253
-      memcpy (&ctx->buffer[left_over], buffer, len);
254
-      left_over += len;
255
-      if (left_over >= 64)
256
-	{
257
-	  md5_process_block (ctx->buffer, 64, ctx);
258
-	  left_over -= 64;
259
-	  memcpy (ctx->buffer, &ctx->buffer[64], left_over);
260
-	}
261
-      ctx->buflen = left_over;
262
-    }
132
+	byteSwap(ctx->buf, 4);
133
+	memcpy(digest, ctx->buf, 16);
134
+	memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
263 135
 }
264 136
 
137
+/* The four core functions - F1 is optimized somewhat */
265 138
 
266
-/* These are the four functions used in the four steps of the MD5 algorithm
267
-   and defined in the RFC 1321.  The first function is a little bit optimized
268
-   (as found in Colin Plumbs public domain implementation).  */
269
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
270
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
271
-#define FG(b, c, d) FF (d, b, c)
272
-#define FH(b, c, d) (b ^ c ^ d)
273
-#define FI(b, c, d) (c ^ (b | ~d))
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))
274 144
 
275
-/* Process LEN bytes of BUFFER, accumulating context into CTX.
276
-   It is assumed that LEN % 64 == 0.  */
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)
277 148
 
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
+ */
278 154
 void
279
-md5_process_block (buffer, len, ctx)
280
-     const void *buffer;
281
-     size_t len;
282
-     struct md5_ctx *ctx;
155
+MD5Transform(uint32_t buf[4], uint32_t const in[16])
283 156
 {
284
-  md5_uint32 correct_words[16];
285
-  const md5_uint32 *words = buffer;
286
-  size_t nwords = len / sizeof (md5_uint32);
287
-  const md5_uint32 *endp = words + nwords;
288
-  md5_uint32 A = ctx->A;
289
-  md5_uint32 B = ctx->B;
290
-  md5_uint32 C = ctx->C;
291
-  md5_uint32 D = ctx->D;
292
-
293
-  /* First increment the byte count.  RFC 1321 specifies the possible
294
-     length of the file up to 2^64 bits.  Here we only compute the
295
-     number of bytes.  Do a double word increment.  */
296
-  ctx->total[0] += len;
297
-  if (ctx->total[0] < len)
298
-    ++ctx->total[1];
299
-
300
-  /* Process all bytes in the buffer with 64 bytes in each round of
301
-     the loop.  */
302
-  while (words < endp)
303
-    {
304
-      md5_uint32 *cwp = correct_words;
305
-      md5_uint32 A_save = A;
306
-      md5_uint32 B_save = B;
307
-      md5_uint32 C_save = C;
308
-      md5_uint32 D_save = D;
309
-
310
-      /* First round: using the given function, the context and a constant
311
-	 the next context is computed.  Because the algorithms processing
312
-	 unit is a 32-bit word and it is determined to work on words in
313
-	 little endian byte order we perhaps have to change the byte order
314
-	 before the computation.  To reduce the work for the next steps
315
-	 we store the swapped words in the array CORRECT_WORDS.  */
316
-
317
-#define OP(a, b, c, d, s, T)						\
318
-      do								\
319
-        {								\
320
-	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
321
-	  ++words;							\
322
-	  CYCLIC (a, s);						\
323
-	  a += b;							\
324
-        }								\
325
-      while (0)
326
-
327
-      /* It is unfortunate that C does not provide an operator for
328
-	 cyclic rotation.  Hope the C compiler is smart enough.  */
329
-#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
330
-
331
-      /* Before we start, one word to the strange constants.
332
-	 They are defined in RFC 1321 as
333
-
334
-	 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
335
-       */
336
-
337
-      /* Round 1.  */
338
-      OP (A, B, C, D,  7, 0xd76aa478);
339
-      OP (D, A, B, C, 12, 0xe8c7b756);
340
-      OP (C, D, A, B, 17, 0x242070db);
341
-      OP (B, C, D, A, 22, 0xc1bdceee);
342
-      OP (A, B, C, D,  7, 0xf57c0faf);
343
-      OP (D, A, B, C, 12, 0x4787c62a);
344
-      OP (C, D, A, B, 17, 0xa8304613);
345
-      OP (B, C, D, A, 22, 0xfd469501);
346
-      OP (A, B, C, D,  7, 0x698098d8);
347
-      OP (D, A, B, C, 12, 0x8b44f7af);
348
-      OP (C, D, A, B, 17, 0xffff5bb1);
349
-      OP (B, C, D, A, 22, 0x895cd7be);
350
-      OP (A, B, C, D,  7, 0x6b901122);
351
-      OP (D, A, B, C, 12, 0xfd987193);
352
-      OP (C, D, A, B, 17, 0xa679438e);
353
-      OP (B, C, D, A, 22, 0x49b40821);
354
-
355
-      /* For the second to fourth round we have the possibly swapped words
356
-	 in CORRECT_WORDS.  Redefine the macro to take an additional first
357
-	 argument specifying the function to use.  */
358
-#undef OP
359
-#define OP(f, a, b, c, d, k, s, T)					\
360
-      do 								\
361
-	{								\
362
-	  a += f (b, c, d) + correct_words[k] + T;			\
363
-	  CYCLIC (a, s);						\
364
-	  a += b;							\
365
-	}								\
366
-      while (0)
367
-
368
-      /* Round 2.  */
369
-      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
370
-      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
371
-      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
372
-      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
373
-      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
374
-      OP (FG, D, A, B, C, 10,  9, 0x02441453);
375
-      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
376
-      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
377
-      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
378
-      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
379
-      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
380
-      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
381
-      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
382
-      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
383
-      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
384
-      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
385
-
386
-      /* Round 3.  */
387
-      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
388
-      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
389
-      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
390
-      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
391
-      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
392
-      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
393
-      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
394
-      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
395
-      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
396
-      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
397
-      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
398
-      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
399
-      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
400
-      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
401
-      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
402
-      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
403
-
404
-      /* Round 4.  */
405
-      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
406
-      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
407
-      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
408
-      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
409
-      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
410
-      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
411
-      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
412
-      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
413
-      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
414
-      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
415
-      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
416
-      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
417
-      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
418
-      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
419
-      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
420
-      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
421
-
422
-      /* Add the starting values of the context.  */
423
-      A += A_save;
424
-      B += B_save;
425
-      C += C_save;
426
-      D += D_save;
427
-    }
428
-
429
-  /* Put checksum in context given as argument.  */
430
-  ctx->A = A;
431
-  ctx->B = B;
432
-  ctx->C = C;
433
-  ctx->D = D;
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;
434 236
 }
... ...
@@ -1,164 +1,37 @@
1
-/* Declaration of functions and data types used for MD5 sum computing
2
-   library functions.
3
-   Copyright (C) 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
4
-   This file is part of the GNU C Library.
5
-
6
-   The GNU C Library is free software; you can redistribute it and/or
7
-   modify it under the terms of the GNU Library General Public License as
8
-   published by the Free Software Foundation; either version 2 of the
9
-   License, or (at your option) any later version.
10
-
11
-   The GNU C Library is distributed in the hope that it will be useful,
12
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
-   Library General Public License for more details.
15
-
16
-   You should have received a copy of the GNU Library General Public
17
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
18
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
-   Boston, MA 02111-1307, USA.  */
20
-
21
-#ifndef _MD5_H
22
-#define _MD5_H 1
23
-
24
-#include <stdio.h>
25
-
26
-#if defined HAVE_LIMITS_H || _LIBC
27
-# include <limits.h>
28
-#endif
29
-
30
-/* The following contortions are an attempt to use the C preprocessor
31
-   to determine an unsigned integral type that is 32 bits wide.  An
32
-   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
33
-   doing that would require that the configure script compile and *run*
34
-   the resulting executable.  Locally running cross-compiled executables
35
-   is usually not possible.  */
36
-
37
-#ifdef _LIBC
38
-# include <sys/types.h>
39
-typedef u_int32_t md5_uint32;
40
-#else
41
-# if defined __STDC__ && __STDC__
42
-#  define UINT_MAX_32_BITS 4294967295U
43
-# else
44
-#  define UINT_MAX_32_BITS 0xFFFFFFFF
45
-# endif
46
-
47
-/* If UINT_MAX isn't defined, assume it's a 32-bit type.
48
-   This should be valid for all systems GNU cares about because
49
-   that doesn't include 16-bit systems, and only modern systems
50
-   (that certainly have <limits.h>) have 64+-bit integral types.  */
51
-
52
-# ifndef UINT_MAX
53
-#  define UINT_MAX UINT_MAX_32_BITS
54
-# endif
55
-
56
-# if UINT_MAX == UINT_MAX_32_BITS
57
-   typedef unsigned int md5_uint32;
58
-# else
59
-#  if USHRT_MAX == UINT_MAX_32_BITS
60
-    typedef unsigned short md5_uint32;
61
-#  else
62
-#   if ULONG_MAX == UINT_MAX_32_BITS
63
-     typedef unsigned long md5_uint32;
64
-#   else
65
-     /* The following line is intended to evoke an error.
66
-        Using #error is not portable enough.  */
67
-     "Cannot determine unsigned 32-bit data type."
68
-#   endif
69
-#  endif
70
-# endif
71
-#endif
72
-
73
-#undef __P
74
-#if defined (__STDC__) && __STDC__
75
-# define __P(x) x
76
-#else
77
-# define __P(x) ()
78
-#endif
79
-
80
-/* Structure to save state of computation between the single steps.  */
81
-struct md5_ctx
82
-{
83
-  md5_uint32 A;
84
-  md5_uint32 B;
85
-  md5_uint32 C;
86
-  md5_uint32 D;
87
-
88
-  md5_uint32 total[2];
89
-  md5_uint32 buflen;
90
-#ifndef __attribute__
91
-  char buffer[128];
92
-#else
93
-  char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
94
-#endif
95
-};
96
-
97
-#ifndef __attribute__
98
-#define __alignof__(a)	sizeof(a)
99
-#endif
100
-
101 1
 /*
102
- * The following three functions are build up the low level used in
103
- * the functions `md5_stream' and `md5_buffer'.
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.
16
+ *
104 17
  */
105 18
 
106
-/* Initialize structure containing state of computation.
107
-   (RFC 1321, 3.3: Step 3)  */
108
-extern void __md5_init_ctx __P ((struct md5_ctx *ctx));
109
-
110
-/* Starting with the result of former calls of this function (or the
111
-   initialization function update the context for the next LEN bytes
112
-   starting at BUFFER.
113
-   It is necessary that LEN is a multiple of 64!!! */
114
-extern void __md5_process_block __P ((const void *buffer, size_t len,
115
-				      struct md5_ctx *ctx));
116
-
117
-/* Starting with the result of former calls of this function (or the
118
-   initialization function update the context for the next LEN bytes
119
-   starting at BUFFER.
120
-   It is NOT required that LEN is a multiple of 64.  */
121
-extern void __md5_process_bytes __P ((const void *buffer, size_t len,
122
-				      struct md5_ctx *ctx));
19
+#ifndef __MD5_H
20
+#define __MD5_H
123 21
 
124
-/* Process the remaining bytes in the buffer and put result from CTX
125
-   in first 16 bytes following RESBUF.  The result is always in little
126
-   endian byte order, so that a byte-wise output yields to the wanted
127
-   ASCII representation of the message digest.
22
+#define md5byte unsigned char
128 23
 
129
-   IMPORTANT: On some systems it is required that RESBUF is correctly
130
-   aligned for a 32 bits value.  */
131
-extern void *__md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
132
-
133
-
134
-/* Put result from CTX in first 16 bytes following RESBUF.  The result is
135
-   always in little endian byte order, so that a byte-wise output yields
136
-   to the wanted ASCII representation of the message digest.
137
-
138
-   IMPORTANT: On some systems it is required that RESBUF is correctly
139
-   aligned for a 32 bits value.  */
140
-extern void *__md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
141
-
142
-
143
-/* Compute MD5 message digest for bytes read from STREAM.  The
144
-   resulting message digest number will be written into the 16 bytes
145
-   beginning at RESBLOCK.  */
146
-extern int __md5_stream __P ((FILE *stream, void *resblock));
147
-
148
-/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
149
-   result is always in little endian byte order, so that a byte-wise
150
-   output yields to the wanted ASCII representation of the message
151
-   digest.  */
152
-extern void *__md5_buffer __P ((const char *buffer, size_t len,
153
-				void *resblock));
24
+#include "cltypes.h"
154 25
 
26
+struct MD5Context {
27
+	uint32_t buf[4];
28
+	uint32_t bytes[2];
29
+	uint32_t in[16];
30
+};
155 31
 
156
-# define md5_init_ctx __md5_init_ctx
157
-# define md5_process_block __md5_process_block
158
-# define md5_process_bytes __md5_process_bytes
159
-# define md5_finish_ctx __md5_finish_ctx
160
-# define md5_read_ctx __md5_read_ctx
161
-# define md5_stream __md5_stream
162
-# define md5_buffer __md5_buffer
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]);
163 36
 
164
-#endif /* md5.h */
37
+#endif
... ...
@@ -163,65 +163,77 @@ const char *cl_perror(int clerror)
163 163
     return cl_strerror(clerror);
164 164
 }
165 165
 
166
-char *cli_md5stream(FILE *fd)
166
+char *cli_md5stream(FILE *fs, unsigned char *digcpy)
167 167
 {
168
-	unsigned char buffer[16];
169
-	char *md5str;
170
-	int i, cnt=0;
168
+	unsigned char digest[16];
169
+	char buff[FILEBUFF];
170
+	struct MD5Context ctx;
171
+	char *md5str, *pt;
172
+	int i, bytes;
173
+
174
+
175
+    MD5Init(&ctx);
176
+
177
+    while((bytes = fread(buff, 1, FILEBUFF, fs)))
178
+	MD5Update(&ctx, buff, bytes);
171 179
 
172
-    md5_stream(fd, &buffer);
180
+    MD5Final(digest, &ctx);
173 181
 
174
-    md5str = (char*) calloc(32 + 1, sizeof(char));
182
+    if(!(md5str = (char *) cli_calloc(32 + 1, sizeof(char))))
183
+	return NULL;
184
+
185
+    pt = md5str;
186
+    for(i = 0; i < 16; i++) {
187
+	sprintf(pt, "%02x", digest[i]);
188
+	pt += 2;
189
+    }
175 190
 
176
-    for(i=0; i<16; i++)
177
-	cnt += sprintf(md5str + cnt, "%02x", buffer[i]);
191
+    if(digcpy)
192
+	memcpy(digcpy, digest, 16);
178 193
 
179
-    return(md5str);
194
+    return md5str;
180 195
 }
181 196
 
182 197
 char *cli_md5file(const char *filename)
183 198
 {
184
-	FILE *fd;
185
-	unsigned char buffer[16];
199
+	FILE *fs;
186 200
 	char *md5str;
187
-	int i, cnt=0;
188 201
 
189 202
 
190
-    if((fd = fopen(filename, "rb")) == NULL) {
203
+    if((fs = fopen(filename, "rb")) == NULL) {
191 204
 	cli_errmsg("cli_md5file(): Can't read file %s\n", filename);
192 205
 	return NULL;
193 206
     }
194 207
 
195
-    md5_stream(fd, &buffer);
196
-    fclose(fd);
208
+    md5str = cli_md5stream(fs, NULL);
209
+    fclose(fs);
197 210
 
198
-    md5str = (char*) calloc(32 + 1, sizeof(char));
199
-
200
-    for(i=0; i<16; i++)
201
-	cnt += sprintf(md5str + cnt, "%02x", buffer[i]);
202
-
203
-    return(md5str);
211
+    return md5str;
204 212
 }
205 213
 
206 214
 static char *cli_md5buff(const char *buffer, unsigned int len)
207 215
 {
208
-	unsigned char md5buff[16];
209
-	char *md5str;
210
-	struct md5_ctx ctx;
211
-	int i, cnt=0;
216
+	unsigned char digest[16];
217
+	char *md5str, *pt;
218
+	struct MD5Context ctx;
219
+	int i;
212 220
 
213 221
 
214
-    md5_init_ctx(&ctx);
215
-    md5_process_bytes(buffer, len, &ctx);
216
-    md5_finish_ctx(&ctx, &md5buff);
217
-    memcpy(oldmd5buff, md5buff, 16);
222
+    MD5Init(&ctx);
223
+    MD5Update(&ctx, buffer, len);
224
+    MD5Final(digest, &ctx);
225
+    memcpy(oldmd5buff, digest, 16);
218 226
 
219
-    md5str = (char*) cli_calloc(32 + 1, sizeof(char));
227
+    if(!(md5str = (char *) cli_calloc(32 + 1, sizeof(char))))
228
+	return NULL;
220 229
 
221
-    for(i=0; i<16; i++)
222
-	cnt += sprintf(md5str + cnt, "%02x", md5buff[i]);
230
+    pt = md5str;
231
+    for(i = 0; i < 16; i++) {
232
+	sprintf(pt, "%02x", digest[i]);
233
+	pt += 2;
234
+    }
223 235
 
224
-    return(md5str);
236
+    return md5str;
225 237
 }
226 238
 
227 239
 void *cli_malloc(size_t size)
... ...
@@ -30,13 +30,13 @@ void *cli_malloc(size_t nmemb);
30 30
 void *cli_calloc(size_t nmemb, size_t size);
31 31
 void *cli_realloc(void *ptr, size_t size);
32 32
 int cli_rmdirs(const char *dirname);
33
-char *cli_md5stream(FILE *fd);
33
+char *cli_md5stream(FILE *fs, unsigned char *digcpy);
34
+char *cli_md5file(const char *filename);
34 35
 int cli_readn(int fd, void *buff, unsigned int count);
35 36
 int cli_writen(int fd, void *buff, unsigned int count);
36 37
 int32_t cli_readint32(const char *buff);
37 38
 char *cli_gentemp(const char *dir);
38 39
 unsigned int cli_rndnum(unsigned int max);
39
-char *cli_md5file(const char *filename);
40 40
 int cli_memstr(const char *haystack, int hs, const char *needle, int ns);
41 41
 
42 42
 #endif
... ...
@@ -123,7 +123,7 @@ void sigtool(struct optstruct *opt)
123 123
 
124 124
 	} else {
125 125
 
126
-	    md5 = cli_md5stream(stdin);
126
+	    md5 = cli_md5stream(stdin, NULL);
127 127
 	    mprintf("%s\n", md5);
128 128
 	    free(md5);
129 129
 	}
... ...
@@ -365,8 +365,9 @@ int build(struct optstruct *opt)
365 365
 
366 366
     /* digital signature */
367 367
     fd = fopen(gzfile, "rb");
368
-    __md5_stream(fd, &buffer);
368
+    pt = cli_md5stream(fd, buffer);
369 369
     fclose(fd);
370
+    free(pt);
370 371
     if(!(pt = getdsig(getargl(opt, "server"), smbuff, buffer))) {
371 372
 	mprintf("No digital signature - no CVD file...\n");
372 373
 	unlink(gzfile);