From nobody@FreeBSD.org  Sat Sep  2 16:57:38 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 379FA16A4DD
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  2 Sep 2006 16:57:38 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id DFDA643D45
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  2 Sep 2006 16:57:37 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k82GvbND043776
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 2 Sep 2006 16:57:37 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k82Gvbjk043775;
	Sat, 2 Sep 2006 16:57:37 GMT
	(envelope-from nobody)
Message-Id: <200609021657.k82Gvbjk043775@www.freebsd.org>
Date: Sat, 2 Sep 2006 16:57:37 GMT
From: Pavel Gorshkov <gorshkov.pavel@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: {SHA1,RIPEMD160}_Update() produce wrong results for large buffers
X-Send-Pr-Version: www-2.3

>Number:         102795
>Category:       kern
>Synopsis:       [libmd] {SHA1,RIPEMD160}_Update() produce wrong results for large buffers
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    cperciva
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 02 17:00:35 GMT 2006
>Closed-Date:    Thu May 24 09:25:02 GMT 2007
>Last-Modified:  Thu May 24 09:25:02 GMT 2007
>Originator:     Pavel Gorshkov
>Release:        6.1-STABLE
>Organization:
>Environment:
FreeBSD localhost 6.1-STABLE FreeBSD 6.1-STABLE #8: Tue May 16 14:22:42 MSD 2006     root@localhost:/usr/obj/usr/src/sys/DESKTOP  i386
>Description:
asm-optimized SHA1_Update() and RIPEMD160_Update() as provided by
libmd.a handle buffers larger than approx. 930M incorrectly
(this is known to happen on 7.0-CURRENT/i386 as well)
>How-To-Repeat:
compile the test program (included at the bottom):

    gcc mdtest.c -o sha1test.shared -lmd
    gcc mdtest.c -o sha1test.static -lmd -static
    gcc -DDO_RMD mdtest.c -o rmd160test.shared -lmd
    gcc -DDO_RMD mdtest.c -o rmd160test.static -lmd -static

create a large test file:

    dd if=/dev/zero bs=32m count=32 of=testfile

run the test program, then verify the results with either openssl or gpg:

    $ ./sha1test.shared testfile
    2a492f15396a6768bcbca016993f4b4c8b0b5307
    $ ./sha1test.static testfile
    0d6ee6083bf8b6368cb80d323e82164e5540e296 <======= WRONG!!!
    $ openssl dgst -sha1 <testfile
    2a492f15396a6768bcbca016993f4b4c8b0b5307
    $ gpg --print-md sha1 <testfile | tr -d ' '
    2A492F15396A6768BCBCA016993F4B4C8B0B5307

    $ ./rmd160test.shared testfile
    eb712b817a49164045b6c7039409e89764bb2b28
    $ ./rmd160test.static testfile
    08890f37f17e739121de6c38c15532c8ff9142a0 <======= WRONG!!!
    $ openssl dgst -ripemd160 <testfile
    eb712b817a49164045b6c7039409e89764bb2b28
    $ gpg --print-md ripemd160 <testfile | tr -d ' '
    EB712B817A49164045B6C7039409E89764BB2B28


/*** mdtest.c ***/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#ifdef DO_RMD
#include <ripemd.h>
RIPEMD160_CTX ctx;
#define MD_INIT     RIPEMD160_Init
#define MD_UPDATE   RIPEMD160_Update
#define MD_FINAL    RIPEMD160_Final
#else
#include <sha.h>
SHA_CTX ctx;
#define MD_INIT     SHA1_Init
#define MD_UPDATE   SHA1_Update
#define MD_FINAL    SHA1_Final
#endif

int main(int argc, char **argv) {
    int fd, i;
    struct stat st;
    unsigned char *buf, digest[20];
    char hexdigest[41];

    if (argc < 2 ||
            stat(argv[1], &st) == -1 ||
            (fd=open(argv[1], O_RDONLY)) == -1 ||
            (buf=mmap(NULL, st.st_size, PROT_READ,
                      MAP_PRIVATE, fd, 0)) == MAP_FAILED)
        return 1;

    MD_INIT(&ctx);
    MD_UPDATE(&ctx, buf, st.st_size);
    MD_FINAL(digest, &ctx);

    for (i = 0; i < 20; ++i)
        sprintf(hexdigest + 2*i, "%02x", digest[i]);
    puts(hexdigest);

    if (st.st_size)
        munmap(buf, st.st_size);
    close(fd);
    return 0;
}
/*** end of mdtest.c ***/

>Fix:

>Release-Note:
>Audit-Trail:

From: Colin Percival <cperciva@freebsd.org>
To: bug-followup@FreeBSD.org, gorshkov.pavel@gmail.com
Cc:  
Subject: Re: kern/102795: [libmd] {SHA1,RIPEMD160}_Update() produce wrong
 results for large buffers
Date: Sun, 13 May 2007 21:43:05 -0700

 I wrote:
 > Can you still reproduce this?  It works fine for me on 6.2-RELEASE [snip]
 
 Ignore this; it turns out that it just needs a slightly larger file in order
 to break now.  I'll commit a patch in a few minutes.
 
 Colin Percival
 

From: Colin Percival <cperciva@freebsd.org>
To: bug-followup@FreeBSD.org, gorshkov.pavel@gmail.com
Cc:  
Subject: Re: kern/102795: [libmd] {SHA1,RIPEMD160}_Update() produce wrong
 results for large buffers
Date: Sun, 13 May 2007 20:44:25 -0700

 Pavel,
 
 Can you still reproduce this?  It works fine for me on 6.2-RELEASE:
 
 $ gcc mdtest.c -o sha1test.shared -lmd
 $ gcc mdtest.c -o sha1test.static -lmd -static
 $ gcc -DDO_RMD mdtest.c -o rmd160test.shared -lmd
 $ gcc -DDO_RMD mdtest.c -o rmd160test.static -lmd -static
 $ truncate -s 1G testfile
 $ ./sha1test.shared testfile
 2a492f15396a6768bcbca016993f4b4c8b0b5307
 $ ./sha1test.static testfile
 2a492f15396a6768bcbca016993f4b4c8b0b5307
 $ openssl dgst -sha1 <testfile
 2a492f15396a6768bcbca016993f4b4c8b0b5307
 $ ./rmd160test.shared testfile
 eb712b817a49164045b6c7039409e89764bb2b28
 $ ./rmd160test.static testfile
 eb712b817a49164045b6c7039409e89764bb2b28
 $ openssl dgst -ripemd160 <testfile
 eb712b817a49164045b6c7039409e89764bb2b28
 
 Colin Percival
 
State-Changed-From-To: open->patched 
State-Changed-By: cperciva 
State-Changed-When: Mon May 14 05:02:20 UTC 2007 
State-Changed-Why:  
Fixed in HEAD. 


Responsible-Changed-From-To: freebsd-bugs->cperciva 
Responsible-Changed-By: cperciva 
Responsible-Changed-When: Mon May 14 05:02:20 UTC 2007 
Responsible-Changed-Why:  
Fixed in HEAD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102795 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/102795: commit references a PR
Date: Mon, 14 May 2007 05:00:44 +0000 (UTC)

 cperciva    2007-05-14 05:00:38 UTC
 
   FreeBSD src repository
 
   Modified files:
     lib/libmd/i386       rmd160.S sha.S 
   Log:
   Use unsigned comparisons.  Prior to this commit, SHA1_Update and
   RIPEMD160_Update were broken when all of the following conditions
   applied:
   (1) The platform is i386.
   (2) The program calling *_Update is statically linked to libmd.
   (3) The buffer provided to *_Update is aligned modulo 4 bytes.
   (4) The buffer extends beyond 2GB.
   
   Due to the design of this code, SHA1_Update and RIPEMD160_Update will
   still be broken if conditions (1)-(3) apply AND the buffer extends
   beyond 4GB (i.e., there is an integer overflow in computing "data + len").
   Since this remaining bug simply replaces SIGSEGV with a bogus hash (and
   non-broken programs should never provide such operands) I don't consider
   it to be a serious problem.
   
   MFC After:      1 week
   PR:             kern/102795
   
   Revision  Changes    Path
   1.4       +2 -1      src/lib/libmd/i386/rmd160.S
   1.3       +2 -1      src/lib/libmd/i386/sha.S
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: cperciva 
State-Changed-When: Thu May 24 09:24:44 UTC 2007 
State-Changed-Why:  
MFCed to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=102795 
>Unformatted:
