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