Date: Wed, 9 May 2007 20:24:38 GMT From: Ighighi<ighighi@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/112553: [patch]: security/digest tiger bug Message-ID: <200705092024.l49KOcgp022588@www.freebsd.org> Resent-Message-ID: <200705092030.l49KU5nL071178@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705092024.l49KOcgp022588>