[git commit] sha384sum: new applet

Denys Vlasenko vda.linux at googlemail.com
Wed Jul 30 16:39:46 UTC 2025


commit: https://git.busybox.net/busybox/commit/?id=dcbb69e0a5cce9058afc5a96b9862982ae17cb39
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
sha512384_end                                          -     198    +198
packed_usage                                       35021   35134    +113
init384                                                -      80     +80
sha384_begin                                           -      19     +19
sha384_end                                             -      10     +10
applet_names                                        2823    2833     +10
md5_sha1_sum_main                                    501     507      +6
sha3_end                                              54      59      +5
applet_main                                         1628    1632      +4
show_usage_if_dash_dash_help                          79      72      -7
hash_file                                            358     344     -14
sha512_end                                           197      10    -187
------------------------------------------------------------------------------
(add/remove: 4/0 grow/shrink: 5/3 up/down: 445/-208)          Total: 237 bytes

Signed-off-by: Andy Knowles <aknowles at galleonec.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 NOFORK_NOEXEC.lst         |  1 +
 coreutils/md5_sha1_sum.c  | 58 +++++++++++++++++++++++++++++++++--------------
 include/libbb.h           |  7 +++++-
 libbb/hash_md5_sha.c      | 58 ++++++++++++++++++++++++++++++++++++-----------
 testsuite/md5sum.tests    |  1 +
 testsuite/sha384sum.tests |  3 +++
 6 files changed, 97 insertions(+), 31 deletions(-)

diff --git a/NOFORK_NOEXEC.lst b/NOFORK_NOEXEC.lst
index 055f9fb24..a000de45b 100644
--- a/NOFORK_NOEXEC.lst
+++ b/NOFORK_NOEXEC.lst
@@ -336,6 +336,7 @@ setuidgid - noexec. spawner
 sha1sum - noexec. runner
 sha256sum - noexec. runner
 sha3sum - noexec. runner
+sha384sum - noexec. runner
 sha512sum - noexec. runner
 showkey - interactive, longterm
 shred - runner
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 978d328f1..4506aeb56 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -23,6 +23,12 @@
 //config:	help
 //config:	Compute and check SHA256 message digest
 //config:
+//config:config SHA384SUM
+//config:	bool "sha384sum (7.3 kb)"
+//config:	default y
+//config:	help
+//config:	Compute and check SHA384 message digest
+//config:
 //config:config SHA512SUM
 //config:	bool "sha512sum (7.3 kb)"
 //config:	default y
@@ -35,13 +41,13 @@
 //config:	help
 //config:	Compute and check SHA3 message digest
 //config:
-//config:comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
-//config:	depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
+//config:comment "Common options for md5sum, sha1sum, sha256sum, ..., sha3sum"
+//config:	depends on MD5SUM || SHA1SUM || SHA256SUM || SHA384SUM || SHA512SUM || SHA3SUM
 //config:
 //config:config FEATURE_MD5_SHA1_SUM_CHECK
 //config:	bool "Enable -c, -s and -w options"
 //config:	default y
-//config:	depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
+//config:	depends on MD5SUM || SHA1SUM || SHA256SUM || SHA384SUM || SHA512SUM || SHA3SUM
 //config:	help
 //config:	Enabling the -c options allows files to be checked
 //config:	against pre-calculated hash values.
@@ -51,11 +57,13 @@
 //applet:IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum))
 //applet:IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum))
 //applet:IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum))
+//applet:IF_SHA384SUM(APPLET_NOEXEC(sha384sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha384sum))
 //applet:IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum))
 
 //kbuild:lib-$(CONFIG_MD5SUM)    += md5_sha1_sum.o
 //kbuild:lib-$(CONFIG_SHA1SUM)   += md5_sha1_sum.o
 //kbuild:lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
+//kbuild:lib-$(CONFIG_SHA384SUM) += md5_sha1_sum.o
 //kbuild:lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
 //kbuild:lib-$(CONFIG_SHA3SUM)   += md5_sha1_sum.o
 
@@ -99,6 +107,16 @@
 //usage:     "\n	-w	Warn about improperly formatted checksum lines"
 //usage:	)
 //usage:
+//usage:#define sha384sum_trivial_usage
+//usage:	IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
+//usage:#define sha384sum_full_usage "\n\n"
+//usage:       "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA384 checksums"
+//usage:	IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
+//usage:     "\n	-c	Check sums against list in FILEs"
+//usage:     "\n	-s	Don't output anything, status code shows success"
+//usage:     "\n	-w	Warn about improperly formatted checksum lines"
+//usage:	)
+//usage:
 //usage:#define sha512sum_trivial_usage
 //usage:	IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
 //usage:#define sha512sum_full_usage "\n\n"
@@ -130,11 +148,12 @@
 
 enum {
 	/* 4th letter of applet_name is... */
-	HASH_MD5 = 's', /* "md5>s<um" */
-	HASH_SHA1 = '1',
+	HASH_MD5    = 's', /* "md5>s<um" */
+	HASH_SHA1   = '1',
 	HASH_SHA256 = '2',
-	HASH_SHA3 = '3',
+	HASH_SHA3   = '3',
 	HASH_SHA512 = '5',
+	/* unfortunately, sha384sum has the same '3' as sha3 */
 };
 
 #define FLAG_SILENT  1
@@ -158,10 +177,11 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
 #endif
 static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned sha3_width)
 {
-	int src_fd, hash_len, count;
+	int src_fd, count;
 	union _ctx_ {
 		sha3_ctx_t sha3;
 		sha512_ctx_t sha512;
+		sha384_ctx_t sha384;
 		sha256_ctx_t sha256;
 		sha1_ctx_t sha1;
 		md5_ctx_t md5;
@@ -183,25 +203,31 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned
 		md5_begin(&context.md5);
 		update = (void*)md5_hash;
 		final = (void*)md5_end;
-		hash_len = 16;
 	}
 	else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) {
 		sha1_begin(&context.sha1);
 		update = (void*)sha1_hash;
 		final = (void*)sha1_end;
-		hash_len = 20;
 	}
 	else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) {
 		sha256_begin(&context.sha256);
 		update = (void*)sha256_hash;
 		final = (void*)sha256_end;
-		hash_len = 32;
+	}
+	else if (ENABLE_SHA384SUM
+	 && (ENABLE_SHA3SUM
+		? (applet_name[4] == '8') /* check for "sha384", but do not match "sha3" */
+		: (hash_algo == '3') /* applet_name = "sha3sum" is not possible */
+		)
+	) {
+		sha384_begin(&context.sha384);
+		update = (void*)sha384_hash;
+		final = (void*)sha384_end;
 	}
 	else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) {
 		sha512_begin(&context.sha512);
 		update = (void*)sha512_hash;
 		final = (void*)sha512_end;
-		hash_len = 64;
 	}
 #if ENABLE_SHA3SUM
 	else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
@@ -219,9 +245,7 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned
 		) {
 			bb_error_msg_and_die("bad -a%u", sha3_width);
 		}
-		sha3_width /= 4;
-		context.sha3.input_block_bytes = 1600/8 - sha3_width;
-		hash_len = sha3_width/2;
+		context.sha3.input_block_bytes = 1600/8 - sha3_width/4;
 	}
 #endif
 	else {
@@ -236,7 +260,7 @@ static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned
 		if (count < 0)
 			bb_perror_msg("can't read '%s'", filename);
 		else /* count == 0 */ {
-			final(&context, in_buf);
+			unsigned hash_len = final(&context, in_buf);
 			hash_value = hash_bin_to_hex(in_buf, hash_len);
 		}
 	}
@@ -262,14 +286,14 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
 		/* -b "binary", -t "text" are ignored (shaNNNsum compat) */
 		/* -s and -w require -c */
 #if ENABLE_SHA3SUM
-		if (applet_name[3] == HASH_SHA3)
+		if (applet_name[3] == HASH_SHA3 && (!ENABLE_SHA384SUM || applet_name[4] != '8'))
 			flags = getopt32(argv, "^" "scwbta:+" "\0" "s?c:w?c", &sha3_width);
 		else
 #endif
 			flags = getopt32(argv, "^" "scwbt" "\0" "s?c:w?c");
 	} else {
 #if ENABLE_SHA3SUM
-		if (applet_name[3] == HASH_SHA3)
+		if (applet_name[3] == HASH_SHA3 && (!ENABLE_SHA384SUM || applet_name[4] != '8'))
 			getopt32(argv, "a:+", &sha3_width);
 		else
 #endif
diff --git a/include/libbb.h b/include/libbb.h
index 4f44680aa..7105bd479 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2209,8 +2209,9 @@ enum {
 	MD5_OUTSIZE    = 16,
 	SHA1_OUTSIZE   = 20,
 	SHA256_OUTSIZE = 32,
+	SHA384_OUTSIZE = 48,
 	SHA512_OUTSIZE = 64,
-	SHA3_OUTSIZE   = 28,
+	//SHA3-224_OUTSIZE = 28,
 	/* size of input block */
 	SHA2_INSIZE     = 64,
 };
@@ -2227,6 +2228,7 @@ typedef struct sha512_ctx_t {
 	uint64_t hash[8];
 	uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
 } sha512_ctx_t;
+typedef struct sha512_ctx_t sha384_ctx_t;
 typedef struct sha3_ctx_t {
 	uint64_t state[25];
 	unsigned bytes_queued;
@@ -2244,6 +2246,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
 void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
 void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
 unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
+void sha384_begin(sha384_ctx_t *ctx) FAST_FUNC;
+#define sha384_hash sha512_hash
+unsigned sha384_end(sha384_ctx_t *ctx, void *resbuf) FAST_FUNC;
 void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
 void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
 unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index 75a61c32c..9ebda232a 100644
--- a/libbb/hash_md5_sha.c
+++ b/libbb/hash_md5_sha.c
@@ -11,7 +11,7 @@
 #define STR1(s) #s
 #define STR(s) STR1(s)
 
-#define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA)
+#define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_SHA384SUM || ENABLE_USE_BB_CRYPT_SHA)
 
 #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL
 # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
@@ -1032,7 +1032,7 @@ static const sha_K_int sha_K[] ALIGN8 = {
 	K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL),
 	K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL),
 	K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL),
-#if NEED_SHA512  /* [64]+ are used for sha512 only */
+#if NEED_SHA512  /* [64]+ are used for sha384 and sha512 only */
 	K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL),
 	K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL),
 	K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL),
@@ -1229,11 +1229,20 @@ static const uint32_t init512_lo[] ALIGN4 = {
 	0x137e2179,
 };
 #endif /* NEED_SHA512 */
-
-// Note: SHA-384 is identical to SHA-512, except that initial hash values are
-// 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
-// 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
-// and the output is constructed by omitting last two 64-bit words of it.
+#if ENABLE_SHA384SUM
+static const uint64_t init384[] ALIGN8 = {
+	0,
+	0,
+	0xcbbb9d5dc1059ed8,
+	0x629a292a367cd507,
+	0x9159015a3070dd17,
+	0x152fecd8f70e5939,
+	0x67332667ffc00b31,
+	0x8eb44a8768581511,
+	0xdb0c2e0d64f98fa7,
+	0x47b5481dbefa4fa4,
+};
+#endif
 
 /* Initialize structure containing state of computation.
    (FIPS 180-2:5.3.2)  */
@@ -1255,9 +1264,19 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
 #endif
 }
 
-#if NEED_SHA512
+#if ENABLE_SHA384SUM
 /* Initialize structure containing state of computation.
    (FIPS 180-2:5.3.3)  */
+void FAST_FUNC sha384_begin(sha512_ctx_t *ctx)
+{
+	memcpy(&ctx->total64, init384, sizeof(init384));
+	/*ctx->total64[0] = ctx->total64[1] = 0; - already done */
+}
+#endif
+
+#if NEED_SHA512
+/* Initialize structure containing state of computation.
+   (FIPS 180-2:5.3.4)  */
 void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
 {
 	int i;
@@ -1332,7 +1351,7 @@ unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 }
 
 #if NEED_SHA512
-unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
+static unsigned FAST_FUNC sha512384_end(sha512_ctx_t *ctx, void *resbuf, unsigned outsize)
 {
 	unsigned bufpos = ctx->total64[0] & 127;
 
@@ -1363,11 +1382,21 @@ unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 		for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
 			ctx->hash[i] = SWAP_BE64(ctx->hash[i]);
 	}
-	memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
-	return sizeof(ctx->hash);
+	memcpy(resbuf, ctx->hash, outsize);
+	return outsize;
+}
+unsigned FAST_FUNC sha512_end(sha384_ctx_t *ctx, void *resbuf)
+{
+	return sha512384_end(ctx, resbuf, SHA512_OUTSIZE);
 }
 #endif /* NEED_SHA512 */
 
+#if ENABLE_SHA384SUM
+unsigned FAST_FUNC sha384_end(sha384_ctx_t *ctx, void *resbuf)
+{
+	return sha512384_end(ctx, resbuf, SHA384_OUTSIZE);
+}
+#endif
 
 /*
  * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
@@ -1904,6 +1933,8 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
 
 unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
 {
+	unsigned hash_len;
+
 	/* Padding */
 	uint8_t *buf = (uint8_t*)ctx->state;
 	/*
@@ -1926,6 +1957,7 @@ unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
 	sha3_process_block72(ctx->state);
 
 	/* Output */
-	memcpy(resbuf, ctx->state, 64);
-	return 64;
+	hash_len = (1600/8 - ctx->input_block_bytes) / 2;
+	memcpy(resbuf, ctx->state, hash_len);
+	return hash_len;
 }
diff --git a/testsuite/md5sum.tests b/testsuite/md5sum.tests
index cca26dc64..634dcd4aa 100755
--- a/testsuite/md5sum.tests
+++ b/testsuite/md5sum.tests
@@ -9,6 +9,7 @@
 # efe30c482e0b687e0cca0612f42ca29b
 # d41337e834377140ae7f98460d71d908598ef04f
 # 8e1d3ed57ebc130f0f72508446559eeae06451ae6d61b1e8ce46370cfb8963c3
+# c01420bb6613d4bd00396a82033e59e81486cbb045ae0dd2b4c3332e581b3ce09fb1946d6e283acec685778ff205d485
 # fe413e0f177324d1353893ca0772ceba83fd41512ba63895a0eebb703ef9feac2fb4e92b2cb430b3bda41b46b0cb4ea8307190a5cc795157cfb680a9cd635d0f
 
 if ! test "$1"; then
diff --git a/testsuite/sha384sum.tests b/testsuite/sha384sum.tests
new file mode 100755
index 000000000..f1449d195
--- /dev/null
+++ b/testsuite/sha384sum.tests
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+. ./md5sum.tests sha384sum c01420bb6613d4bd00396a82033e59e81486cbb045ae0dd2b4c3332e581b3ce09fb1946d6e283acec685778ff205d485


More information about the busybox-cvs mailing list