NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

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



>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---




Home | Main Index | Thread Index | Old Index