From owner-freebsd-stable@FreeBSD.ORG Tue Jan 10 00:09:07 2006 Return-Path: X-Original-To: freebsd-stable@freebsd.org Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9A6AD16A41F for ; Tue, 10 Jan 2006 00:09:07 +0000 (GMT) (envelope-from gorshkov.pavel@gmail.com) Received: from ppp85-140-169-214.pppoe.mtu-net.ru (ppp85-140-169-214.pppoe.mtu-net.ru [85.140.169.214]) by mx1.FreeBSD.org (Postfix) with ESMTP id 98FB743D46 for ; Tue, 10 Jan 2006 00:09:06 +0000 (GMT) (envelope-from gorshkov.pavel@gmail.com) Received: from localhost (localhost [IPv6:::1]) by localhost.my.domain (8.13.4/8.13.4) with ESMTP id k09Nxr9m003090 for ; Tue, 10 Jan 2006 02:59:54 +0300 (MSK) (envelope-from gorshkov.pavel@gmail.com) Date: Tue, 10 Jan 2006 02:59:53 +0300 From: Pavel Gorshkov To: freebsd-stable@freebsd.org Message-ID: <20060109235953.GA2868@localhost> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="WIyZ46R2i8wDzkSu" Content-Disposition: inline X-Operating-System: FreeBSD 6.0-STABLE i386 X-Editor: Vim-604 http://www.vim.org User-Agent: mutt-ng/devel-r655 (FreeBSD) Subject: SHA1_Update() produces wrong results for large buffers X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Jan 2006 00:09:07 -0000 --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline An important detail to begin with is that our libmd.a, as opposed to libmd.so, provides a faster, assembly-optimized version of the `SHA1_Update' function (it is not compatible with PIC and is therefore not used in libmd.so). The problem is that the asm-optimized version fails on large input buffers. Attached is a test program, which mmaps a file and then just feeds its contents to SHA1_Update(): gcc sha1test.c -o sha1test.md-shared -lmd gcc sha1test.c -o sha1test.md-static -lmd -static the input files: dd if=/dev/zero bs=32M count=48 of=test-1.5G dd if=/dev/zero bs=32M count=32 of=test-1G dd if=/dev/zero bs=32M count=16 of=test-0.5G *** # exits immediately, displaying a WRONG hash value ./sha1test.md-static test-1.5G 747cd7172ce7737d1735cf936c0d69ce0f733fcd # OK ./sha1test.md-shared test-1.5G a957f01b1a92366c7b72296cb24eb84f42ed06e4 *** ./sha1test.md-static test-1G 0d6ee6083bf8b6368cb80d323e82164e5540e296 # ^^^ WRONG # OK ./sha1test.md-shared test-1G 2a492f15396a6768bcbca016993f4b4c8b0b5307 However, both programs work fine with files less than ~920M: ./sha1test.md-static test-0.5G 5b088492c9f4778f409b7ae61477dec124c99033 ./sha1test.md-shared test-0.5G 5b088492c9f4778f409b7ae61477dec124c99033 Everything was tested on a RELENG_6/i386 box (CFLAGS = -O2). Is this a bug in libmd, or am I missing something? Thanks in advance, -- Pavel Gorshkov --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sha1test.c" #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int fd; struct stat st; SHA_CTX ctx; unsigned char *buf; char hexdigest[41]; if (argc < 2 || stat(argv[1], &st) < 0 || (fd=open(argv[1], O_RDONLY)) < 0) exit(1); if ((buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) exit(1); SHA1_Init(&ctx); SHA1_Update(&ctx, buf, st.st_size); SHA1_End(&ctx, hexdigest); puts(hexdigest); if (st.st_size) munmap(buf, st.st_size); close(fd); return 0; } --WIyZ46R2i8wDzkSu--