aboutsummaryrefslogtreecommitdiff
path: root/libbb/md5.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/md5.c')
-rw-r--r--libbb/md5.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/libbb/md5.c b/libbb/md5.c
index cf3825a34..a1f0a923f 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -418,31 +418,30 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
*/
void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
{
- uint64_t total;
- unsigned i;
unsigned bufpos = BUFPOS(ctx);
-
- /* Pad data to block size. */
+ /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
ctx->buffer[bufpos++] = 0x80;
- memset(ctx->buffer + bufpos, 0, 64 - bufpos);
- if (bufpos > 56) {
+ /* This loop iterates either once or twice, no more, no less */
+ while (1) {
+ unsigned remaining = 64 - bufpos;
+ memset(ctx->buffer + bufpos, 0, remaining);
+ /* Do we have enough space for the length count? */
+ if (remaining >= 8) {
+ /* Store the 64-bit counter of bits in the buffer in BE format */
+ uint64_t t = ctx->total << 3;
+ unsigned i;
+ for (i = 0; i < 8; i++) {
+ ctx->buffer[56 + i] = t;
+ t >>= 8;
+ }
+ }
md5_hash_block(ctx);
- memset(ctx->buffer, 0, 64);
- }
-
- /* Put the 64-bit file length, expressed in *bits*,
- * at the end of the buffer.
- */
- total = ctx->total << 3;
- for (i = 0; i < 8; i++) {
- ctx->buffer[56 + i] = total;
- total >>= 8;
+ if (remaining >= 8)
+ break;
+ bufpos = 0;
}
- /* Process last bytes. */
- md5_hash_block(ctx);
-
/* The MD5 result is in little endian byte order.
* We (ab)use the fact that A-D are consecutive in memory.
*/