ports/112553: [patch]: security/digest tiger bug
Ighighi
ighighi at gmail.com
Wed May 9 20:30:06 UTC 2007
>Number: 112553
>Category: ports
>Synopsis: [patch]: security/digest tiger bug
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed May 09 20:30:05 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Ighighi
>Release: 6.2-STABLE
>Organization:
>Environment:
FreeBSD orion 6.2-STABLE FreeBSD 6.2-STABLE #1: Sat May 5 10:13:59 VET 2007 root at orion:/usr/obj/usr/src/sys/CUSTOM i386
>Description:
This patch makes Tiger output the correct checksum for the null string.
Previously, hashing /dev/null or the null string (echo -n "") would output the contents of the initial Tiger context.
$ digest tiger /dev/null
TIGER (/dev/null) = 0123456789abcdeffedcba9876543210f096a5b4c3b2e187
It should be:
$ ./digest tiger /dev/null
TIGER (/dev/null) = 24f0130c63ac933216166e76b1bb925ff373de2d49584e7a
See: http://www.cs.technion.ac.il/~biham/Reports/Tiger/testresults.html
The bug is in the Tiger code (not digest) because the emulation of the MD*/SHA* interface isn't well done. When any of the *End() or *Final() is called after finishing a hash operation on zero-byte data, it must make sure the relevant update function (in this case, TigerUpdate) was called at least once, even with len=0. This patch just adds a 192-bit static array containing the initial Tiger state (which now uses TigerInit()) that both TigerEnd() and TigerFinal() use to compare it to tiger_context_t (which contains just a Tiger state). A "less cleaner" way would be to add an integer flag to tiger_context_t. It also makes TigerFinal() truly emulate the MD*/SHA*Final() calls. This (trivial) patch to tiger.c was tested on a 32-bit Pentium-4 (little endian) running FreeBSD 6.2-STABLE and a Sun SPARC (big endian) running SunOS 5.10. IMO, it could have been spotted earlier with a better test script. The remaining algorithms work OK with the null string.
Note: This patch was tested against the current NetBSD's CVS version of pkgsrc/digest/files/tiger.c (as of this time of writing, version 1.2) and FreeBSD's (present in ports/security/digest) and (currently installed as digest-20050323_1.
http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/pkgtools/digest/files/tiger.c
To apply this patch on a FreeBSD system copy this patch to /usr/ports/security/digest/files as patch-tiger.c.patch and reinstall
The original author (agc at netbsd.org) was notified. These comments are reproduced on the patch for your convenience.
>How-To-Repeat:
>Fix:
Attached is a UUEncoded patch.
Patch attached with submission follows:
--- tiger.c.orig Tue May 8 06:31:30 2007
+++ tiger.c Tue May 8 08:07:57 2007
@@ -646,12 +646,16 @@
TIGER_COMPRESS_MACRO(((const uint64_t *) str), ((uint64_t *) state));
}
+static uint64_t init_state[3] = {
+ 0x0123456789ABCDEFLL, 0xFEDCBA9876543210LL, 0xF096A5B4C3B2E187LL
+};
+
void
TIGERInit(tiger_context_t *tp)
{
- tp->ctx[0] = 0x0123456789ABCDEFLL;
- tp->ctx[1] = 0xFEDCBA9876543210LL;
- tp->ctx[2] = 0xF096A5B4C3B2E187LL;
+ tp->ctx[0] = init_state[0];
+ tp->ctx[1] = init_state[1];
+ tp->ctx[2] = init_state[2];
}
void
@@ -708,10 +712,27 @@
tiger_compress(((uint64_t *) temp), tp->ctx);
}
+#define PUT_64BIT_BE(cp, value) do { \
+ (cp)[0] = (value) >> 56; \
+ (cp)[1] = (value) >> 48; \
+ (cp)[2] = (value) >> 40; \
+ (cp)[3] = (value) >> 32; \
+ (cp)[4] = (value) >> 24; \
+ (cp)[5] = (value) >> 16; \
+ (cp)[6] = (value) >> 8; \
+ (cp)[7] = (value); } while (0)
+
void
TIGERFinal(uint8_t *digest, tiger_context_t *tp)
{
- /* nothing to do - included for compatibility with SHA* interface */
+ int i;
+
+ if (tp->ctx[0] == init_state[0] && tp->ctx[1] == init_state[1] &&
+ tp->ctx[2] == init_state[2])
+ TIGERUpdate(tp, "", 0);
+
+ for (i = 0; i < 3; i++)
+ PUT_64BIT_BE(digest + i * 8, tp->ctx[i]);
}
static void
@@ -734,6 +755,9 @@
if (buf == NULL && (buf = malloc(41)) == NULL) {
return NULL;
}
+ if (tp->ctx[0] == init_state[0] && tp->ctx[1] == init_state[1] &&
+ tp->ctx[2] == init_state[2])
+ TIGERUpdate(tp, "", 0);
for (i = 0; i < 3; ++i)
print_uint64(buf + i * 16, tp->ctx[i]);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list