1/* md5sum.c - Compute MD5 checksum of files or strings according to the
2 *            definition of MD5 in RFC 1321 from April 1992.
3 * Copyright (C) 1995-1999 Free Software Foundation, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu> */
21/* Hacked to work with BusyBox by Alfred M. Szmidt <ams@trillian.itslinux.org> */
22
23/*
24 * June 29, 2001        Manuel Novoa III
25 *
26 * Added MD5SUM_SIZE_VS_SPEED configuration option.
27 *
28 * Current valid values, with data from my system for comparison, are:
29 *   (using uClibc and running on linux-2.4.4.tar.bz2)
30 *                     user times (sec)  text size (386)
31 *     0 (fastest)         1.1                6144
32 *     1                   1.4                5392
33 *     2                   3.0                5088
34 *     3 (smallest)        5.1                4912
35 */
36
37#define MD5SUM_SIZE_VS_SPEED 2
38
39/**********************************************************************/
40
41#include <stdio.h>
42#include <errno.h>
43#include <ctype.h>
44#include <getopt.h>
45#include <stdlib.h>
46#include <string.h>
47#include <endian.h>
48#include <sys/types.h>
49#if defined HAVE_LIMITS_H
50# include <limits.h>
51#endif
52#include "busybox.h"
53
54/* For some silly reason, this file uses backwards TRUE and FALSE conventions */
55#undef TRUE
56#undef FALSE
57#define FALSE   ((int) 1)
58#define TRUE    ((int) 0)
59
60//----------------------------------------------------------------------------
61//--------md5.c
62//----------------------------------------------------------------------------
63
64/* md5.c - Functions to compute MD5 message digest of files or memory blocks
65 *         according to the definition of MD5 in RFC 1321 from April 1992.
66 */
67
68/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
69
70//----------------------------------------------------------------------------
71//--------md5.h
72//----------------------------------------------------------------------------
73
74/* md5.h - Declaration of functions and data types used for MD5 sum
75   computing library functions. */
76
77typedef u_int32_t md5_uint32;
78
79/* Structure to save state of computation between the single steps.  */
80struct md5_ctx
81{
82  md5_uint32 A;
83  md5_uint32 B;
84  md5_uint32 C;
85  md5_uint32 D;
86
87  md5_uint32 total[2];
88  md5_uint32 buflen;
89  char buffer[128];
90};
91
92/*
93 * The following three functions are build up the low level used in
94 * the functions `md5_stream' and `md5_buffer'.
95 */
96
97/* Initialize structure containing state of computation.
98   (RFC 1321, 3.3: Step 3)  */
99static void md5_init_ctx __P ((struct md5_ctx *ctx));
100
101/* Starting with the result of former calls of this function (or the
102   initialization function update the context for the next LEN bytes
103   starting at BUFFER.
104   It is necessary that LEN is a multiple of 64!!! */
105static void md5_process_block __P ((const void *buffer, size_t len,
106				    struct md5_ctx *ctx));
107
108/* Starting with the result of former calls of this function (or the
109   initialization function update the context for the next LEN bytes
110   starting at BUFFER.
111   It is NOT required that LEN is a multiple of 64.  */
112static void md5_process_bytes __P ((const void *buffer, size_t len,
113				    struct md5_ctx *ctx));
114
115/* Process the remaining bytes in the buffer and put result from CTX
116   in first 16 bytes following RESBUF.  The result is always in little
117   endian byte order, so that a byte-wise output yields to the wanted
118   ASCII representation of the message digest.
119
120   IMPORTANT: On some systems it is required that RESBUF is correctly
121   aligned for a 32 bits value.  */
122static void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
123
124
125
126
127/* Compute MD5 message digest for bytes read from STREAM.  The
128   resulting message digest number will be written into the 16 bytes
129   beginning at RESBLOCK.  */
130static int md5_stream __P ((FILE *stream, void *resblock));
131
132/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
133   result is always in little endian byte order, so that a byte-wise
134   output yields to the wanted ASCII representation of the message
135   digest.  */
136static void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
137
138//----------------------------------------------------------------------------
139//--------end of md5.h
140//----------------------------------------------------------------------------
141
142/* Handle endian-ness */
143#if __BYTE_ORDER == __LITTLE_ENDIAN
144	#define SWAP(n) (n)
145#else
146	#define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
147#endif
148
149
150
151#if MD5SUM_SIZE_VS_SPEED == 0
152/* This array contains the bytes used to pad the buffer to the next
153   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
154static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */  };
155#endif
156
157/* Initialize structure containing state of computation.
158   (RFC 1321, 3.3: Step 3)  */
159void md5_init_ctx(struct md5_ctx *ctx)
160{
161  ctx->A = 0x67452301;
162  ctx->B = 0xefcdab89;
163  ctx->C = 0x98badcfe;
164  ctx->D = 0x10325476;
165
166  ctx->total[0] = ctx->total[1] = 0;
167  ctx->buflen = 0;
168}
169
170/* Process the remaining bytes in the internal buffer and the usual
171   prolog according to the standard and write the result to RESBUF.
172
173   IMPORTANT: On some systems it is required that RESBUF is correctly
174   aligned for a 32 bits value.  */
175static void *md5_finish_ctx(struct md5_ctx *ctx, void *resbuf)
176{
177  /* Take yet unprocessed bytes into account.  */
178  md5_uint32 bytes = ctx->buflen;
179  size_t pad;
180
181  /* Now count remaining bytes.  */
182  ctx->total[0] += bytes;
183  if (ctx->total[0] < bytes)
184    ++ctx->total[1];
185
186  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
187#if MD5SUM_SIZE_VS_SPEED > 0
188  memset(&ctx->buffer[bytes], 0, pad);
189  ctx->buffer[bytes] = 0x80;
190#else
191  memcpy(&ctx->buffer[bytes], fillbuf, pad);
192#endif
193
194  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
195  *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
196  *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] =
197    SWAP( ((ctx->total[1] << 3) | (ctx->total[0] >> 29)) );
198
199  /* Process last bytes.  */
200  md5_process_block(ctx->buffer, bytes + pad + 8, ctx);
201
202/* Put result from CTX in first 16 bytes following RESBUF.  The result is
203   always in little endian byte order, so that a byte-wise output yields
204   to the wanted ASCII representation of the message digest.
205
206   IMPORTANT: On some systems it is required that RESBUF is correctly
207   aligned for a 32 bits value.  */
208  ((md5_uint32 *) resbuf)[0] = SWAP(ctx->A);
209  ((md5_uint32 *) resbuf)[1] = SWAP(ctx->B);
210  ((md5_uint32 *) resbuf)[2] = SWAP(ctx->C);
211  ((md5_uint32 *) resbuf)[3] = SWAP(ctx->D);
212
213  return resbuf;
214}
215
216/* Compute MD5 message digest for bytes read from STREAM.  The
217   resulting message digest number will be written into the 16 bytes
218   beginning at RESBLOCK.  */
219static int md5_stream(FILE *stream, void *resblock)
220{
221  /* Important: BLOCKSIZE must be a multiple of 64.  */
222static const int BLOCKSIZE = 4096;
223  struct md5_ctx ctx;
224  char buffer[BLOCKSIZE + 72];
225  size_t sum;
226
227  /* Initialize the computation context.  */
228  md5_init_ctx(&ctx);
229
230  /* Iterate over full file contents.  */
231  while (1) {
232    /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
233       computation function processes the whole buffer so that with the
234       next round of the loop another block can be read.  */
235    size_t n;
236    sum = 0;
237
238    /* Read block.  Take care for partial reads.  */
239    do {
240      n = fread(buffer + sum, 1, BLOCKSIZE - sum, stream);
241
242      sum += n;
243    }
244    while (sum < BLOCKSIZE && n != 0);
245    if (n == 0 && ferror(stream))
246      return 1;
247
248    /* If end of file is reached, end the loop.  */
249    if (n == 0)
250      break;
251
252    /* Process buffer with BLOCKSIZE bytes.  Note that
253       BLOCKSIZE % 64 == 0
254    */
255    md5_process_block(buffer, BLOCKSIZE, &ctx);
256  }
257
258  /* Add the last bytes if necessary.  */
259  if (sum > 0)
260    md5_process_bytes(buffer, sum, &ctx);
261
262  /* Construct result in desired memory.  */
263  md5_finish_ctx(&ctx, resblock);
264  return 0;
265}
266
267/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
268   result is always in little endian byte order, so that a byte-wise
269   output yields to the wanted ASCII representation of the message
270   digest.  */
271static void *md5_buffer(const char *buffer, size_t len, void *resblock)
272{
273  struct md5_ctx ctx;
274
275  /* Initialize the computation context.  */
276  md5_init_ctx(&ctx);
277
278  /* Process whole buffer but last len % 64 bytes.  */
279  md5_process_bytes(buffer, len, &ctx);
280
281  /* Put result in desired memory area.  */
282  return md5_finish_ctx(&ctx, resblock);
283}
284
285static void md5_process_bytes(const void *buffer, size_t len, struct md5_ctx *ctx)
286{
287  /* When we already have some bits in our internal buffer concatenate
288     both inputs first.  */
289  if (ctx->buflen != 0) {
290    size_t left_over = ctx->buflen;
291    size_t add = 128 - left_over > len ? len : 128 - left_over;
292
293    memcpy(&ctx->buffer[left_over], buffer, add);
294    ctx->buflen += add;
295
296    if (left_over + add > 64) {
297      md5_process_block(ctx->buffer, (left_over + add) & ~63, ctx);
298      /* The regions in the following copy operation cannot overlap.  */
299      memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
300	     (left_over + add) & 63);
301      ctx->buflen = (left_over + add) & 63;
302    }
303
304    buffer = (const char *) buffer + add;
305    len -= add;
306  }
307
308  /* Process available complete blocks.  */
309  if (len > 64) {
310    md5_process_block(buffer, len & ~63, ctx);
311    buffer = (const char *) buffer + (len & ~63);
312    len &= 63;
313  }
314
315  /* Move remaining bytes in internal buffer.  */
316  if (len > 0) {
317    memcpy(ctx->buffer, buffer, len);
318    ctx->buflen = len;
319  }
320}
321
322/* These are the four functions used in the four steps of the MD5 algorithm
323   and defined in the RFC 1321.  The first function is a little bit optimized
324   (as found in Colin Plumbs public domain implementation).  */
325/* #define FF(b, c, d) ((b & c) | (~b & d)) */
326#define FF(b, c, d) (d ^ (b & (c ^ d)))
327#define FG(b, c, d) FF (d, b, c)
328#define FH(b, c, d) (b ^ c ^ d)
329#define FI(b, c, d) (c ^ (b | ~d))
330
331/* Process LEN bytes of BUFFER, accumulating context into CTX.
332   It is assumed that LEN % 64 == 0.  */
333static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx)
334{
335  md5_uint32 correct_words[16];
336  const md5_uint32 *words = buffer;
337  size_t nwords = len / sizeof(md5_uint32);
338  const md5_uint32 *endp = words + nwords;
339#if MD5SUM_SIZE_VS_SPEED > 0
340  static const md5_uint32 C_array[] = {
341      /* round 1 */
342      0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
343      0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
344      0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
345      0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
346      /* round 2 */
347      0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
348      0xd62f105d, 0x2441453,  0xd8a1e681, 0xe7d3fbc8,
349      0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
350      0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
351      /* round 3 */
352      0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
353      0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
354      0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
355      0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
356      /* round 4 */
357      0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
358      0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
359      0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
360      0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
361  };
362
363  static const char P_array[] = {
364#if MD5SUM_SIZE_VS_SPEED > 1
365      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
366#endif
367      1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
368      5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
369      0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9  /* 4 */
370  };
371
372#if MD5SUM_SIZE_VS_SPEED > 1
373  static const char S_array[] = {
374      7, 12, 17, 22,
375      5, 9, 14, 20,
376      4, 11, 16, 23,
377      6, 10, 15, 21
378  };
379#endif
380#endif
381
382  md5_uint32 A = ctx->A;
383  md5_uint32 B = ctx->B;
384  md5_uint32 C = ctx->C;
385  md5_uint32 D = ctx->D;
386
387  /* First increment the byte count.  RFC 1321 specifies the possible
388     length of the file up to 2^64 bits.  Here we only compute the
389     number of bytes.  Do a double word increment.  */
390  ctx->total[0] += len;
391  if (ctx->total[0] < len)
392    ++ctx->total[1];
393
394  /* Process all bytes in the buffer with 64 bytes in each round of
395     the loop.  */
396  while (words < endp) {
397    md5_uint32 *cwp = correct_words;
398    md5_uint32 A_save = A;
399    md5_uint32 B_save = B;
400    md5_uint32 C_save = C;
401    md5_uint32 D_save = D;
402
403#if MD5SUM_SIZE_VS_SPEED > 1
404#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
405
406    const md5_uint32 *pc;
407    const char *pp;
408    const char *ps;
409    int i;
410    md5_uint32 temp;
411
412    for ( i=0 ; i < 16 ; i++ ) {
413	cwp[i] = SWAP(words[i]);
414    }
415    words += 16;
416
417#if MD5SUM_SIZE_VS_SPEED > 2
418    pc = C_array; pp = P_array; ps = S_array - 4;
419
420    for ( i = 0 ; i < 64 ; i++ ) {
421	if ((i&0x0f) == 0) ps += 4;
422	temp = A;
423	switch (i>>4) {
424	    case 0:
425		temp += FF(B,C,D);
426		break;
427	    case 1:
428		temp += FG(B,C,D);
429		break;
430	    case 2:
431		temp += FH(B,C,D);
432		break;
433	    case 3:
434		temp += FI(B,C,D);
435	}
436	temp += cwp[(int)(*pp++)] + *pc++;
437	temp = CYCLIC (temp, ps[i&3]);
438	temp += B;
439	A = D; D = C; C = B; B = temp;
440    }
441#else
442    pc = C_array; pp = P_array; ps = S_array;
443
444    for ( i = 0 ; i < 16 ; i++ ) {
445	temp = A + FF(B,C,D) + cwp[(int)(*pp++)] + *pc++;
446	temp = CYCLIC (temp, ps[i&3]);
447	temp += B;
448	A = D; D = C; C = B; B = temp;
449    }
450
451    ps += 4;
452    for ( i = 0 ; i < 16 ; i++ ) {
453	temp = A + FG(B,C,D) + cwp[(int)(*pp++)] + *pc++;
454	temp = CYCLIC (temp, ps[i&3]);
455	temp += B;
456	A = D; D = C; C = B; B = temp;
457    }
458    ps += 4;
459    for ( i = 0 ; i < 16 ; i++ ) {
460	temp = A + FH(B,C,D) + cwp[(int)(*pp++)] + *pc++;
461	temp = CYCLIC (temp, ps[i&3]);
462	temp += B;
463	A = D; D = C; C = B; B = temp;
464    }
465    ps += 4;
466    for ( i = 0 ; i < 16 ; i++ ) {
467	temp = A + FI(B,C,D) + cwp[(int)(*pp++)] + *pc++;
468	temp = CYCLIC (temp, ps[i&3]);
469	temp += B;
470	A = D; D = C; C = B; B = temp;
471    }
472
473#endif
474#else
475    /* First round: using the given function, the context and a constant
476       the next context is computed.  Because the algorithms processing
477       unit is a 32-bit word and it is determined to work on words in
478       little endian byte order we perhaps have to change the byte order
479       before the computation.  To reduce the work for the next steps
480       we store the swapped words in the array CORRECT_WORDS.  */
481
482#define OP(a, b, c, d, s, T)						\
483      do								\
484        {								\
485	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;		\
486	  ++words;							\
487	  CYCLIC (a, s);						\
488	  a += b;							\
489        }								\
490      while (0)
491
492    /* It is unfortunate that C does not provide an operator for
493       cyclic rotation.  Hope the C compiler is smart enough.  */
494    /* gcc 2.95.4 seems to be --aaronl */
495#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
496
497    /* Before we start, one word to the strange constants.
498       They are defined in RFC 1321 as
499
500       T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
501    */
502
503#if MD5SUM_SIZE_VS_SPEED == 1
504    const md5_uint32 *pc;
505    const char *pp;
506    int i;
507#endif
508
509    /* Round 1.  */
510#if MD5SUM_SIZE_VS_SPEED == 1
511    pc = C_array;
512    for ( i=0 ; i < 4 ; i++ ) {
513	OP(A, B, C, D, 7, *pc++);
514	OP(D, A, B, C, 12, *pc++);
515	OP(C, D, A, B, 17, *pc++);
516	OP(B, C, D, A, 22, *pc++);
517    }
518#else
519    OP(A, B, C, D, 7, 0xd76aa478);
520    OP(D, A, B, C, 12, 0xe8c7b756);
521    OP(C, D, A, B, 17, 0x242070db);
522    OP(B, C, D, A, 22, 0xc1bdceee);
523    OP(A, B, C, D, 7, 0xf57c0faf);
524    OP(D, A, B, C, 12, 0x4787c62a);
525    OP(C, D, A, B, 17, 0xa8304613);
526    OP(B, C, D, A, 22, 0xfd469501);
527    OP(A, B, C, D, 7, 0x698098d8);
528    OP(D, A, B, C, 12, 0x8b44f7af);
529    OP(C, D, A, B, 17, 0xffff5bb1);
530    OP(B, C, D, A, 22, 0x895cd7be);
531    OP(A, B, C, D, 7, 0x6b901122);
532    OP(D, A, B, C, 12, 0xfd987193);
533    OP(C, D, A, B, 17, 0xa679438e);
534    OP(B, C, D, A, 22, 0x49b40821);
535#endif
536
537    /* For the second to fourth round we have the possibly swapped words
538       in CORRECT_WORDS.  Redefine the macro to take an additional first
539       argument specifying the function to use.  */
540#undef OP
541#define OP(f, a, b, c, d, k, s, T)					\
542      do 								\
543	{								\
544	  a += f (b, c, d) + correct_words[k] + T;			\
545	  CYCLIC (a, s);						\
546	  a += b;							\
547	}								\
548      while (0)
549
550    /* Round 2.  */
551#if MD5SUM_SIZE_VS_SPEED == 1
552    pp = P_array;
553    for ( i=0 ; i < 4 ; i++ ) {
554	OP(FG, A, B, C, D, (int)(*pp++), 5, *pc++);
555	OP(FG, D, A, B, C, (int)(*pp++), 9, *pc++);
556	OP(FG, C, D, A, B, (int)(*pp++), 14, *pc++);
557	OP(FG, B, C, D, A, (int)(*pp++), 20, *pc++);
558    }
559#else
560    OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
561    OP(FG, D, A, B, C, 6, 9, 0xc040b340);
562    OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
563    OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
564    OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
565    OP(FG, D, A, B, C, 10, 9, 0x02441453);
566    OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
567    OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
568    OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
569    OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
570    OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
571    OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
572    OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
573    OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
574    OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
575    OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
576#endif
577
578    /* Round 3.  */
579#if MD5SUM_SIZE_VS_SPEED == 1
580    for ( i=0 ; i < 4 ; i++ ) {
581	OP(FH, A, B, C, D, (int)(*pp++), 4, *pc++);
582	OP(FH, D, A, B, C, (int)(*pp++), 11, *pc++);
583	OP(FH, C, D, A, B, (int)(*pp++), 16, *pc++);
584	OP(FH, B, C, D, A, (int)(*pp++), 23, *pc++);
585    }
586#else
587    OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
588    OP(FH, D, A, B, C, 8, 11, 0x8771f681);
589    OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
590    OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
591    OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
592    OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
593    OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
594    OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
595    OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
596    OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
597    OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
598    OP(FH, B, C, D, A, 6, 23, 0x04881d05);
599    OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
600    OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
601    OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
602    OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
603#endif
604
605    /* Round 4.  */
606#if MD5SUM_SIZE_VS_SPEED == 1
607    for ( i=0 ; i < 4 ; i++ ) {
608	OP(FI, A, B, C, D, (int)(*pp++), 6, *pc++);
609	OP(FI, D, A, B, C, (int)(*pp++), 10, *pc++);
610	OP(FI, C, D, A, B, (int)(*pp++), 15, *pc++);
611	OP(FI, B, C, D, A, (int)(*pp++), 21, *pc++);
612    }
613#else
614    OP(FI, A, B, C, D, 0, 6, 0xf4292244);
615    OP(FI, D, A, B, C, 7, 10, 0x432aff97);
616    OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
617    OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
618    OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
619    OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
620    OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
621    OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
622    OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
623    OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
624    OP(FI, C, D, A, B, 6, 15, 0xa3014314);
625    OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
626    OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
627    OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
628    OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
629    OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
630#endif
631#endif
632
633    /* Add the starting values of the context.  */
634    A += A_save;
635    B += B_save;
636    C += C_save;
637    D += D_save;
638  }
639
640  /* Put checksum in context given as argument.  */
641  ctx->A = A;
642  ctx->B = B;
643  ctx->C = C;
644  ctx->D = D;
645}
646
647//----------------------------------------------------------------------------
648//--------end of md5.c
649//----------------------------------------------------------------------------
650
651#define ISWHITE(c) ((c) == ' ' || (c) == '\t')
652#define ISXDIGIT(c) (isxdigit (c))
653
654/* The minimum length of a valid digest line in a file produced
655   by `md5sum FILE' and read by `md5sum -c'.  This length does
656   not include any newline character at the end of a line.  */
657static const int MIN_DIGEST_LINE_LENGTH = 35; /* 32 - message digest length
658                                      2 - blank and binary indicator
659                                      1 - minimum filename length */
660
661static int have_read_stdin; /* Nonzero if any of the files read were
662                               the standard input. */
663
664static int status_only = 0; /* With -c, don't generate any output.
665                               The exit code indicates success or failure */
666static int warn = 0; /* With -w, print a message to standard error warning
667                        about each improperly formatted MD5 checksum line */
668
669static int split_3(char *s,
670                   size_t s_len,
671                   unsigned char **u,
672                   char **w)
673{
674  size_t i = 0;
675  int escaped_filename = 0;
676
677  while (ISWHITE(s[i]))
678    ++i;
679
680  /* The line must have at least 35 (36 if the first is a backslash)
681     more characters to contain correct message digest information.
682     Ignore this line if it is too short.  */
683  if (!(s_len - i >= MIN_DIGEST_LINE_LENGTH
684        || (s[i] == '\\' && s_len - i >= 1 + MIN_DIGEST_LINE_LENGTH)))
685    return FALSE;
686
687  if (s[i] == '\\') {
688    ++i;
689    escaped_filename = 1;
690  }
691  *u = (unsigned char *) &s[i];
692
693  /* The first field has to be the 32-character hexadecimal
694     representation of the message digest.  If it is not followed
695     immediately by a white space it's an error.  */
696  i += 32;
697  if (!ISWHITE(s[i]))
698    return FALSE;
699
700  s[i++] = '\0';
701
702  if (s[i] != ' ' && s[i++] != '*')
703    return FALSE;
704
705  /* All characters between the type indicator and end of line are
706     significant -- that includes leading and trailing white space.  */
707  *w = &s[i];
708
709  if (escaped_filename) {
710    /* Translate each `\n' string in the file name to a NEWLINE,
711       and each `\\' string to a backslash.  */
712
713    char *dst = &s[i];
714
715    while (i < s_len) {
716      switch (s[i]) {
717       case '\\':
718        if (i == s_len - 1) {
719          /* A valid line does not end with a backslash.  */
720          return FALSE;
721        }
722        ++i;
723        switch (s[i++]) {
724         case 'n':
725          *dst++ = '\n';
726          break;
727         case '\\':
728          *dst++ = '\\';
729          break;
730         default:
731          /* Only `\' or `n' may follow a backslash.  */
732          return FALSE;
733        }
734        break;
735
736       case '\0':
737        /* The file name may not contain a NUL.  */
738        return FALSE;
739        break;
740
741       default:
742        *dst++ = s[i++];
743        break;
744      }
745    }
746    *dst = '\0';
747  }
748  return TRUE;
749}
750
751static inline int hex_digits(unsigned char const *s)
752{
753  while (*s) {
754    if (!ISXDIGIT(*s))
755      return TRUE;
756    ++s;
757  }
758  return FALSE;
759}
760
761/* An interface to md5_stream.  Operate on FILENAME (it may be "-") and
762   put the result in *MD5_RESULT.  Return non-zero upon failure, zero
763   to indicate success.  */
764static int md5_file(const char *filename,
765                    unsigned char *md5_result)
766{
767  FILE *fp;
768
769  if (filename[0] == '-' && filename[1] == '\0') {
770    have_read_stdin = 1;
771    fp = stdin;
772  } else {
773    fp = wfopen(filename, "r");
774    if (fp == NULL)
775      return FALSE;
776    }
777
778  if (md5_stream(fp, md5_result)) {
779    perror_msg("%s", filename);
780
781    if (fp != stdin)
782      fclose(fp);
783    return FALSE;
784  }
785
786  if (fp != stdin && fclose(fp) == EOF) {
787    perror_msg("%s", filename);
788    return FALSE;
789  }
790
791  return TRUE;
792}
793
794static int md5_check(const char *checkfile_name)
795{
796  FILE *checkfile_stream;
797  int n_properly_formated_lines = 0;
798  int n_mismatched_checksums = 0;
799  int n_open_or_read_failures = 0;
800  unsigned char md5buffer[16];
801  size_t line_number;
802  char line[BUFSIZ];
803
804  if (checkfile_name[0] == '-' && checkfile_name[1] == '\0') {
805    have_read_stdin = 1;
806    checkfile_stream = stdin;
807  } else {
808    checkfile_stream = wfopen(checkfile_name, "r");
809    if (checkfile_stream == NULL)
810      return FALSE;
811    }
812
813  line_number = 0;
814
815  do {
816    char *filename;
817    unsigned char *md5num;
818    int line_length;
819
820    ++line_number;
821
822    fgets(line, BUFSIZ-1, checkfile_stream);
823    line_length = strlen(line);
824
825    if (line_length <= 0 || line==NULL)
826      break;
827
828    /* Ignore comment lines, which begin with a '#' character.  */
829    if (line[0] == '#')
830      continue;
831
832    /* Remove any trailing newline.  */
833    if (line[line_length - 1] == '\n')
834      line[--line_length] = '\0';
835
836    if (split_3(line, line_length, &md5num, &filename)
837        || !hex_digits(md5num)) {
838      if (warn) {
839        error_msg("%s: %lu: improperly formatted MD5 checksum line",
840                 checkfile_name, (unsigned long) line_number);
841      }
842    } else {
843      static const char bin2hex[] = {
844        '0', '1', '2', '3',
845        '4', '5', '6', '7',
846        '8', '9', 'a', 'b',
847        'c', 'd', 'e', 'f'
848      };
849
850      ++n_properly_formated_lines;
851
852      if (md5_file(filename, md5buffer)) {
853        ++n_open_or_read_failures;
854        if (!status_only) {
855          printf("%s: FAILED open or read\n", filename);
856          fflush(stdout);
857        }
858      } else {
859        size_t cnt;
860        /* Compare generated binary number with text representation
861           in check file.  Ignore case of hex digits.  */
862        for (cnt = 0; cnt < 16; ++cnt) {
863          if (tolower(md5num[2 * cnt])
864              != bin2hex[md5buffer[cnt] >> 4]
865              || (tolower(md5num[2 * cnt + 1])
866                  != (bin2hex[md5buffer[cnt] & 0xf])))
867            break;
868        }
869        if (cnt != 16)
870          ++n_mismatched_checksums;
871
872        if (!status_only) {
873          printf("%s: %s\n", filename,
874                 (cnt != 16 ? "FAILED" : "OK"));
875          fflush(stdout);
876        }
877      }
878    }
879  }
880
881  while (!feof(checkfile_stream) && !ferror(checkfile_stream));
882
883  if (ferror(checkfile_stream)) {
884    error_msg("%s: read error", checkfile_name);
885    return FALSE;
886  }
887
888  if (checkfile_stream != stdin && fclose(checkfile_stream) == EOF) {
889    perror_msg("md5sum: %s", checkfile_name);
890    return FALSE;
891  }
892
893  if (n_properly_formated_lines == 0) {
894    /* Warn if no tests are found.  */
895    error_msg("%s: no properly formatted MD5 checksum lines found",
896             checkfile_name);
897    return FALSE;
898  } else {
899    if (!status_only) {
900      int n_computed_checkums = (n_properly_formated_lines
901                                 - n_open_or_read_failures);
902
903      if (n_open_or_read_failures > 0) {
904        error_msg("WARNING: %d of %d listed files could not be read",
905                 n_open_or_read_failures, n_properly_formated_lines);
906        return FALSE;
907      }
908
909      if (n_mismatched_checksums > 0) {
910        error_msg("WARNING: %d of %d computed checksums did NOT match",
911                 n_mismatched_checksums, n_computed_checkums);
912        return FALSE;
913      }
914    }
915  }
916
917  return ((n_properly_formated_lines > 0 && n_mismatched_checksums == 0
918           && n_open_or_read_failures == 0) ? 0 : 1);
919}
920
921int md5sum_main(int argc,
922                char **argv)
923{
924  unsigned char md5buffer[16];
925  int do_check = 0;
926  int opt;
927  char **string = NULL;
928  size_t n_strings = 0;
929  size_t err = 0;
930  char file_type_specified = 0;
931  char binary = 0;
932
933  while ((opt = getopt(argc, argv, "g:bcstw")) != -1) {
934    switch (opt) {
935     case 'g': { /* read a string */
936       if (string == NULL)
937         string = (char **) xmalloc ((argc - 1) * sizeof (char *));
938
939       string[n_strings++] = optarg;
940       break;
941     }
942
943     case 'b': /* read files in binary mode */
944      file_type_specified = 1;
945      binary = 1;
946      break;
947
948     case 'c': /* check MD5 sums against given list */
949      do_check = 1;
950      break;
951
952     case 's':  /* don't output anything, status code shows success */
953      status_only = 1;
954      warn = 0;
955      break;
956
957     case 't': /* read files in text mode (default) */
958      file_type_specified = 1;
959      binary = 0;
960      break;
961
962     case 'w': /* warn about improperly formated MD5 checksum lines */
963      status_only = 0;
964      warn = 1;
965      break;
966
967     default:
968      show_usage();
969    }
970  }
971
972  if (file_type_specified && do_check) {
973    error_msg_and_die("the -b and -t options are meaningless when verifying checksums");
974  }
975
976  if (n_strings > 0 && do_check) {
977    error_msg_and_die("the -g and -c options are mutually exclusive");
978  }
979
980  if (status_only && !do_check) {
981    error_msg_and_die("the -s option is meaningful only when verifying checksums");
982  }
983
984  if (warn && !do_check) {
985    error_msg_and_die("the -w option is meaningful only when verifying checksums");
986  }
987
988  if (n_strings > 0) {
989    size_t i;
990
991    if (optind < argc) {
992      error_msg_and_die("no files may be specified when using -g");
993    }
994    for (i = 0; i < n_strings; ++i) {
995      size_t cnt;
996      md5_buffer (string[i], strlen (string[i]), md5buffer);
997
998      for (cnt = 0; cnt < 16; ++cnt)
999        printf ("%02x", md5buffer[cnt]);
1000
1001      printf ("  \"%s\"\n", string[i]);
1002    }
1003  } else if (do_check) {
1004    if (optind + 1 < argc) {
1005      error_msg("only one argument may be specified when using -c");
1006    }
1007
1008    err = md5_check ((optind == argc) ? "-" : argv[optind]);
1009  } else {
1010    if (optind == argc)
1011      argv[argc++] = "-";
1012
1013    for (; optind < argc; ++optind) {
1014      int fail;
1015      char *file = argv[optind];
1016
1017      fail = md5_file (file, md5buffer);
1018      err |= fail;
1019      if (!fail && file[0]=='-' && file[1] == '\0') {
1020	  size_t i;
1021	  for (i = 0; i < 16; ++i)
1022	      printf ("%02x", md5buffer[i]);
1023	  putchar ('\n');
1024      } else if (!fail) {
1025        size_t i;
1026        /* Output a leading backslash if the file name contains
1027           a newline or backslash.  */
1028        if (strchr (file, '\n') || strchr (file, '\\'))
1029          putchar ('\\');
1030
1031        for (i = 0; i < 16; ++i)
1032          printf ("%02x", md5buffer[i]);
1033
1034        putchar (' ');
1035        if (binary)
1036          putchar ('*');
1037        else
1038          putchar (' ');
1039
1040        /* Translate each NEWLINE byte to the string, "\\n",
1041           and each backslash to "\\\\".  */
1042        for (i = 0; i < strlen (file); ++i) {
1043          switch (file[i]) {
1044           case '\n':
1045            fputs ("\\n", stdout);
1046            break;
1047
1048           case '\\':
1049            fputs ("\\\\", stdout);
1050            break;
1051
1052           default:
1053            putchar (file[i]);
1054            break;
1055          }
1056        }
1057        putchar ('\n');
1058      }
1059    }
1060  }
1061
1062  if (fclose (stdout) == EOF) {
1063    error_msg_and_die("write error");
1064  }
1065
1066  if (have_read_stdin && fclose (stdin) == EOF) {
1067    error_msg_and_die("standard input");
1068  }
1069
1070  if (err == 0)
1071	  return EXIT_SUCCESS;
1072  else
1073	  return EXIT_FAILURE;
1074}
1075