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