aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/md5_sha1_sum.c2
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/md5.c129
3 files changed, 44 insertions, 89 deletions
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 633b6e534..eeee18449 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -71,7 +71,7 @@ static uint8_t *hash_file(const char *filename, hash_algo_t hash_algo)
71 bb_error_msg_and_die("algorithm not supported"); 71 bb_error_msg_and_die("algorithm not supported");
72 } 72 }
73 73
74 while (0 < (count = read(src_fd, in_buf, sizeof in_buf))) { 74 while (0 < (count = read(src_fd, in_buf, 4096))) {
75 update(in_buf, count, &context); 75 update(in_buf, count, &context);
76 } 76 }
77 77
diff --git a/include/libbb.h b/include/libbb.h
index 39361a232..02927cd77 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -506,7 +506,7 @@ typedef struct _md5_ctx_t_ {
506 uint32_t B; 506 uint32_t B;
507 uint32_t C; 507 uint32_t C;
508 uint32_t D; 508 uint32_t D;
509 uint32_t total[2]; 509 uint64_t total;
510 uint32_t buflen; 510 uint32_t buflen;
511 char buffer[128]; 511 char buffer[128];
512} md5_ctx_t; 512} md5_ctx_t;
diff --git a/libbb/md5.c b/libbb/md5.c
index b5aa89fc6..584f5fe6f 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -33,15 +33,9 @@
33# elif defined(bswap_32) 33# elif defined(bswap_32)
34# define SWAP(n) bswap_32(n) 34# define SWAP(n) bswap_32(n)
35# else 35# else
36# define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24)) 36# define SWAP(n) ((n << 24) | ((n&0xFF00)<<8) | ((n&0xFF0000)>>8) | (n>>24))
37# endif 37# endif
38 38
39# if MD5_SIZE_VS_SPEED == 0
40/* This array contains the bytes used to pad the buffer to the next
41 64-byte boundary. (RFC 1321, 3.1: Step 1) */
42static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
43# endif /* MD5_SIZE_VS_SPEED == 0 */
44
45/* Initialize structure containing state of computation. 39/* Initialize structure containing state of computation.
46 * (RFC 1321, 3.3: Step 3) 40 * (RFC 1321, 3.3: Step 3)
47 */ 41 */
@@ -52,7 +46,7 @@ void md5_begin(md5_ctx_t *ctx)
52 ctx->C = 0x98badcfe; 46 ctx->C = 0x98badcfe;
53 ctx->D = 0x10325476; 47 ctx->D = 0x10325476;
54 48
55 ctx->total[0] = ctx->total[1] = 0; 49 ctx->total = 0;
56 ctx->buflen = 0; 50 ctx->buflen = 0;
57} 51}
58 52
@@ -66,17 +60,11 @@ void md5_begin(md5_ctx_t *ctx)
66# define FH(b, c, d) (b ^ c ^ d) 60# define FH(b, c, d) (b ^ c ^ d)
67# define FI(b, c, d) (c ^ (b | ~d)) 61# define FI(b, c, d) (c ^ (b | ~d))
68 62
69/* Starting with the result of former calls of this function (or the 63/* Hash a single block, 64 bytes long and 4-byte aligned. */
70 * initialization function update the context for the next LEN bytes 64static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
71 * starting at BUFFER.
72 * It is necessary that LEN is a multiple of 64!!!
73 */
74static void md5_hash_block(const void *buffer, size_t len, md5_ctx_t *ctx)
75{ 65{
76 uint32_t correct_words[16]; 66 uint32_t correct_words[16];
77 const uint32_t *words = buffer; 67 const uint32_t *words = buffer;
78 size_t nwords = len / sizeof(uint32_t);
79 const uint32_t *endp = words + nwords;
80 68
81# if MD5_SIZE_VS_SPEED > 0 69# if MD5_SIZE_VS_SPEED > 0
82 static const uint32_t C_array[] = { 70 static const uint32_t C_array[] = {
@@ -126,16 +114,8 @@ static void md5_hash_block(const void *buffer, size_t len, md5_ctx_t *ctx)
126 uint32_t C = ctx->C; 114 uint32_t C = ctx->C;
127 uint32_t D = ctx->D; 115 uint32_t D = ctx->D;
128 116
129 /* First increment the byte count. RFC 1321 specifies the possible
130 length of the file up to 2^64 bits. Here we only compute the
131 number of bytes. Do a double word increment. */
132 ctx->total[0] += len;
133 if (ctx->total[0] < len)
134 ++ctx->total[1];
135
136 /* Process all bytes in the buffer with 64 bytes in each round of 117 /* Process all bytes in the buffer with 64 bytes in each round of
137 the loop. */ 118 the loop. */
138 while (words < endp) {
139 uint32_t *cwp = correct_words; 119 uint32_t *cwp = correct_words;
140 uint32_t A_save = A; 120 uint32_t A_save = A;
141 uint32_t B_save = B; 121 uint32_t B_save = B;
@@ -397,7 +377,6 @@ static void md5_hash_block(const void *buffer, size_t len, md5_ctx_t *ctx)
397 B += B_save; 377 B += B_save;
398 C += C_save; 378 C += C_save;
399 D += D_save; 379 D += D_save;
400 }
401 380
402 /* Put checksum in context given as argument. */ 381 /* Put checksum in context given as argument. */
403 ctx->A = A; 382 ctx->A = A;
@@ -406,55 +385,39 @@ static void md5_hash_block(const void *buffer, size_t len, md5_ctx_t *ctx)
406 ctx->D = D; 385 ctx->D = D;
407} 386}
408 387
409/* Starting with the result of former calls of this function (or the 388/* Feed data through a temporary buffer to call md5_hash_aligned_block()
410 * initialization function update the context for the next LEN bytes 389 * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
411 * starting at BUFFER. 390 * This function's internal buffer remembers previous data until it has 64
412 * It is NOT required that LEN is a multiple of 64. 391 * bytes worth to pass on. Call md5_end() to flush this buffer. */
413 */
414 392
415static void md5_hash_bytes(const void *buffer, size_t len, md5_ctx_t *ctx) 393void md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
416{ 394{
417 /* When we already have some bits in our internal buffer concatenate 395 char *buf=(char *)buffer;
418 both inputs first. */
419 if (ctx->buflen != 0) {
420 size_t left_over = ctx->buflen;
421 size_t add = 128 - left_over > len ? len : 128 - left_over;
422
423 memcpy(&ctx->buffer[left_over], buffer, add);
424 ctx->buflen += add;
425
426 if (left_over + add > 64) {
427 md5_hash_block(ctx->buffer, (left_over + add) & ~63, ctx);
428 /* The regions in the following copy operation cannot overlap. */
429 memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
430 (left_over + add) & 63);
431 ctx->buflen = (left_over + add) & 63;
432 }
433 396
434 buffer = (const char *) buffer + add; 397 /* RFC 1321 specifies the possible length of the file up to 2^64 bits,
435 len -= add; 398 * Here we only track the number of bytes. */
436 }
437 399
438 /* Process available complete blocks. */ 400 ctx->total += len;
439 if (len > 64) {
440 md5_hash_block(buffer, len & ~63, ctx);
441 buffer = (const char *) buffer + (len & ~63);
442 len &= 63;
443 }
444 401
445 /* Move remaining bytes in internal buffer. */ 402 // Process all input.
446 if (len > 0) {
447 memcpy(ctx->buffer, buffer, len);
448 ctx->buflen = len;
449 }
450}
451 403
452void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) 404 while (len) {
453{ 405 int i = 64 - ctx->buflen;
454 if (length % 64 == 0) { 406
455 md5_hash_block(data, length, ctx); 407 // Copy data into aligned buffer.
456 } else { 408
457 md5_hash_bytes(data, length, ctx); 409 if (i > len) i = len;
410 memcpy(ctx->buffer + ctx->buflen, buf, i);
411 len -= i;
412 ctx->buflen += i;
413 buf += i;
414
415 // When buffer fills up, process it.
416
417 if (ctx->buflen == 64) {
418 md5_hash_block(ctx->buffer, ctx);
419 ctx->buflen = 0;
420 }
458 } 421 }
459} 422}
460 423
@@ -468,31 +431,23 @@ void md5_hash(const void *data, size_t length, md5_ctx_t *ctx)
468 */ 431 */
469void *md5_end(void *resbuf, md5_ctx_t *ctx) 432void *md5_end(void *resbuf, md5_ctx_t *ctx)
470{ 433{
471 /* Take yet unprocessed bytes into account. */ 434 char *buf = ctx->buffer;
472 uint32_t bytes = ctx->buflen; 435 int i;
473 size_t pad;
474 436
475 /* Now count remaining bytes. */ 437 /* Pad data to block size. */
476 ctx->total[0] += bytes;
477 if (ctx->total[0] < bytes)
478 ++ctx->total[1];
479 438
480 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; 439 buf[ctx->buflen++] = 0x80;
481# if MD5_SIZE_VS_SPEED > 0 440 memset(buf + ctx->buflen, 0, 128 - ctx->buflen);
482 memset(&ctx->buffer[bytes], 0, pad);
483 ctx->buffer[bytes] = 0x80;
484# else
485 memcpy(&ctx->buffer[bytes], fillbuf, pad);
486# endif /* MD5_SIZE_VS_SPEED > 0 */
487 441
488 /* Put the 64-bit file length in *bits* at the end of the buffer. */ 442 /* Put the 64-bit file length in *bits* at the end of the buffer. */
489 *(uint32_t *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3); 443 ctx->total <<= 3;
490 *(uint32_t *) & ctx->buffer[bytes + pad + 4] = 444 if (ctx->buflen > 56) buf += 64;
491 SWAP(((ctx->total[1] << 3) | (ctx->total[0] >> 29))); 445 for (i = 0; i < 8; i++) buf[56 + i] = ctx->total >> (i*8);
492 446
493 /* Process last bytes. */ 447 /* Process last bytes. */
494 md5_hash_block(ctx->buffer, bytes + pad + 8, ctx); 448 if (buf != ctx->buffer) md5_hash_block(ctx->buffer, ctx);
495 449 md5_hash_block(buf, ctx);
450
496 /* Put result from CTX in first 16 bytes following RESBUF. The result is 451 /* Put result from CTX in first 16 bytes following RESBUF. The result is
497 * always in little endian byte order, so that a byte-wise output yields 452 * always in little endian byte order, so that a byte-wise output yields
498 * to the wanted ASCII representation of the message digest. 453 * to the wanted ASCII representation of the message digest.