diff options
-rw-r--r-- | coreutils/md5_sha1_sum.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | libbb/md5.c | 129 |
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) */ | ||
42 | static 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 | 64 | static 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 | */ | ||
74 | static 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 | ||
415 | static void md5_hash_bytes(const void *buffer, size_t len, md5_ctx_t *ctx) | 393 | void 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 | ||
452 | void 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 | */ |
469 | void *md5_end(void *resbuf, md5_ctx_t *ctx) | 432 | void *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. |