lib/60442: sha256(1) etc. are slow

"[email protected] via gnats" <[email protected]>
Newsgroups gmane.os.netbsd.bugs
Message-ID <[email protected]>
>Number:         60442
>Category:       lib
>Synopsis:       sha256(1) etc. are slow
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 12 07:45:00 +0000 2026
>Originator:     RVP
>Release:        NetBSD/amd64 11.99.6
>Organization:
>Environment:
NetBSD/amd64 11.99.6
>Description:
The has utilities (sha256, sha512, etc.) are slow because the
HASH_File(3) functions read 1K (BUFSIZ) at a time.
>How-To-Repeat:
;; The standard utility.
;;
$ time -p sha256 /mnt/tmp/nbsd/NetBSD-11.0_RC5-amd64.iso
SHA256 (/mnt/tmp/nbsd/NetBSD-11.0_RC5-amd64.iso) = d2213a21ad1526f78942df74411fd01e626fb76702f9425c3ca42387b6410a89
real 7.73
user 4.08
sys 3.62       ; <--

;; Prog. using SHA256_Init(3) etc. w/ a 32KB buffer.
;;
$ time -p ./sha256 /mnt/tmp/nbsd/NetBSD-11.0_RC5-amd64.iso
SHA256 (/mnt/tmp/nbsd/NetBSD-11.0_RC5-amd64.iso) = d2213a21ad1526f78942df74411fd01e626fb76702f9425c3ca42387b6410a89
real 4.35
user 3.83
sys 0.51       ; <--

$
>Fix:
1. Use a 32KB buffer.

2. Call the *_End(3) always to clear the context.

3. cat /SOME/FILE | sha256 /dev/stdin
   doesn't work properly because *_File(3) routine seems geared to
   reading mostly regular/blk. special files. Maybe this needs change?

---START patch---
diff -urN lib/libc/hash.orig/hashhl.c lib/libc/hash/hashhl.c
--- lib/libc/hash.orig/hashhl.c	2023-09-04 20:51:39.000000000 +0000
+++ lib/libc/hash/hashhl.c	2026-06-21 22:20:04.954996261 +0000
@@ -88,12 +88,16 @@
 char *
 FNPREFIX(FileChunk)(const char *filename, char *buf, off_t off, off_t len)
 {
+	enum { BSIZ = 32 * 1024 };	/* at least 8KB */
 	struct stat sb;
-	u_char buffer[BUFSIZ];
+	u_char* buffer;
 	HASH_CTX ctx;
 	int fd, save_errno;
 	ssize_t nr;
 
+	if (len < 0 || off < 0)
+		return (NULL);
+
 	FNPREFIX(Init)(&ctx);
 
 	if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) < 0)
@@ -109,18 +113,23 @@
 		close(fd);
 		return (NULL);
 	}
+	if ((buffer = malloc(BSIZ)) == NULL) {
+		close(fd);
+		return (NULL);
+	}
 
-	while ((nr = read(fd, buffer, (size_t) MIN((off_t)sizeof(buffer), len)))
-	    > 0) {
+	while ((nr = read(fd, buffer, (size_t)MIN((off_t)BSIZ, len))) > 0) {
 		FNPREFIX(Update)(&ctx, buffer, (unsigned int)nr);
 		if (len > 0 && (len -= nr) == 0)
 			break;
 	}
+	char* res = FNPREFIX(End)(&ctx, buf);
+	free(buffer);
 
 	save_errno = errno;
 	close(fd);
 	errno = save_errno;
-	return (nr < 0 ? NULL : FNPREFIX(End)(&ctx, buf));
+	return (nr < 0) ? NULL : res;
 }
 
 char *
---END patch---
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.