This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH #14090] md5_process_block() produces incorrect resultwith large block sizes
- From: Andreas Jaeger <aj at suse dot com>
- To: libc-alpha at sourceware dot org
- Date: Sat, 19 May 2012 20:07:01 +0200
- Subject: Re: [PATCH #14090] md5_process_block() produces incorrect resultwith large block sizes
- References: <4FB78EBB.9060206@suse.com>
sha512.c has theoretically the same problem iff we don't use
USE_TOTAL128 (which is set for WORDSIZE64):
>From bugzilla:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In crypt/sha512.c:123:
#ifdef USE_TOTAL128
ctx->total128 += len;
#else
ctx->total[TOTAL128_low] += len;
if (ctx->total[TOTAL128_low] < len)
++ctx->total[TOTAL128_high];
#endif
But only in remotely hypothetical case of !USE_TOTAL128 and 128-bit size_t and
then only if someone actually calls sha512_process_block() with this huge
buffer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here's a patch - or should we just ignore it?
Tested on Linux/x86,
Andreas
* crypt/sha512.c (sha512_process_block): Likewise.
diff --git a/crypt/sha512.c b/crypt/sha512.c
index 6e531c5..84fbce1 100644
--- a/crypt/sha512.c
+++ b/crypt/sha512.c
@@ -1,6 +1,6 @@
/* Functions to compute SHA512 message digest of files or memory blocks.
according to the definition of SHA512 in FIPS 180-2.
- Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2007-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -116,16 +116,18 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
uint64_t f = ctx->H[5];
uint64_t g = ctx->H[6];
uint64_t h = ctx->H[7];
-
+#ifndef USE_TOTAL128
+ uint64_t lolen = len;
+#endif
/* First increment the byte count. FIPS 180-2 specifies the possible
length of the file up to 2^128 bits. Here we only compute the
number of bytes. Do a double word increment. */
#ifdef USE_TOTAL128
ctx->total128 += len;
#else
- ctx->total[TOTAL128_low] += len;
- if (ctx->total[TOTAL128_low] < len)
- ++ctx->total[TOTAL128_high];
+ ctx->total[TOTAL128_low] += lolen;
+ ctx->total[TOTAL128_high] += ((uint64_t)len >> 63 >> 1)
+ + (ctx->total [TOTAL128_low] < lolen);
#endif
/* Process all bytes in the buffer with 128 bytes in each round of
--
Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126