cksum: prefer -a sha2 -l ###, to -a sha###

To make the interface more concise and consistent,
while being backwards compatible.

* src/digest.c (main): Continue to support -a "sha###" but
also support -a "sha2" and treat it like "sha3", except in...
(output_file): ... maintain the legacy tags for better compatability.
* doc/coreutils.texi (cksum invocation): Document the -a sha2 option.
* tests/cksum/cksum-base64.pl: Adjust as per modified --help.
* tests/cksum/cksum-c.sh: Add new supported SHA2-### tagged variant.
* NEWS: Mention the new feature.
This commit is contained in:
Pádraig Brady
2025-09-02 15:28:21 +01:00
parent 403d82a0bf
commit aba9800995
6 changed files with 88 additions and 42 deletions

4
NEWS
View File

@@ -91,6 +91,10 @@ GNU coreutils NEWS -*- outline -*-
SHA3-256, SHA3-384, SHA3-512 message digest algorithms depending on
the argument passed to the required --length (-l) option.
'cksum -a' now supports the 'sha2' argument, as a more consistent
interface than the existing 'sha224', 'sha256', 'sha384', 'sha512'
arguments, which are now selected with the --length (-l) option.
'date' now outputs dates in the country's native calendar for the
Iranian locale (fa_IR) and for the Ethiopian locale (am_ET), and also
does so more consistently for the Thailand locale (th_TH.UTF-8).

View File

@@ -4147,10 +4147,7 @@ Supported more modern digest algorithms are:
@example
@samp{md5} equivalent to @command{md5sum}
@samp{sha1} equivalent to @command{sha1sum}
@samp{sha224} equivalent to @command{sha224sum}
@samp{sha256} equivalent to @command{sha256sum}
@samp{sha384} equivalent to @command{sha384sum}
@samp{sha512} equivalent to @command{sha512sum}
@samp{sha2} equivalent to @command{sha@{224,256,384,512@}sum}
@samp{sha3} only available through @command{cksum}
@samp{blake2b} equivalent to @command{b2sum}
@samp{sm3} only available through @command{cksum}
@@ -4181,10 +4178,10 @@ like the checksum implementation being used.
@opindex --length
@cindex BLAKE2 hash length
@cindex SHA-3 hash length
Specify the digest size used with @option{-a sha3} or @option{-a blake2b}.
Specify the digest size used with @option{-a sha2, sha3, or blake2b}.
For @samp{blake2b} this is optional, with 512 being the default. If the
option is given it must be a multiple of 8. For @samp{sha3} this option
is required, and the @var{length} must be one of 224, 256, 384, or 512.
option is given it must be a multiple of 8. For @samp{sha2} or @samp{sha3} this
option is required, and the @var{length} must be one of 224, 256, 384, or 512.
This option is ignored when @option{--check} is specified,
as the length is automatically determined when checking.

View File

@@ -287,6 +287,23 @@ sha512_sum_stream (FILE *stream, void *resstream,
return sha512_stream (stream, resstream);
}
static int
sha2_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
{
switch (*length)
{
case SHA224_DIGEST_SIZE:
return sha224_stream (stream, resstream);
case SHA256_DIGEST_SIZE:
return sha256_stream (stream, resstream);
case SHA384_DIGEST_SIZE:
return sha384_stream (stream, resstream);
case SHA512_DIGEST_SIZE:
return sha512_stream (stream, resstream);
default:
unreachable ();
}
}
static int
sha3_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
{
switch (*length)
@@ -326,6 +343,7 @@ enum Algorithm
sha256,
sha384,
sha512,
sha2,
sha3,
blake2b,
sm3,
@@ -333,25 +351,29 @@ enum Algorithm
static char const *const algorithm_args[] =
{
"bsd", "sysv", "crc", "crc32b", "md5", "sha1", "sha224",
"sha256", "sha384", "sha512", "sha3", "blake2b", "sm3", nullptr
"bsd", "sysv", "crc", "crc32b", "md5", "sha1",
"sha224", "sha256", "sha384", "sha512", /* Legacy naming */
"sha2", "sha3", "blake2b", "sm3", nullptr
};
static enum Algorithm const algorithm_types[] =
{
bsd, sysv, crc, crc32b, md5, sha1, sha224,
sha256, sha384, sha512, sha3, blake2b, sm3,
bsd, sysv, crc, crc32b, md5, sha1,
sha224, sha256, sha384, sha512,
sha2, sha3, blake2b, sm3,
};
ARGMATCH_VERIFY (algorithm_args, algorithm_types);
static char const *const algorithm_tags[] =
{
"BSD", "SYSV", "CRC", "CRC32B", "MD5", "SHA1", "SHA224",
"SHA256", "SHA384", "SHA512", "SHA3", "BLAKE2b", "SM3", nullptr
"BSD", "SYSV", "CRC", "CRC32B", "MD5", "SHA1",
"SHA224", "SHA256", "SHA384", "SHA512",
"SHA2", "SHA3", "BLAKE2b", "SM3", nullptr
};
static int const algorithm_bits[] =
{
16, 16, 32, 32, 128, 160, 224,
256, 384, 512, 512, 512, 256, 0
16, 16, 32, 32, 128, 160,
224, 256, 384, 512,
512, 512, 512, 256, 0
};
static_assert (ARRAY_CARDINALITY (algorithm_bits)
@@ -371,6 +393,7 @@ static sumfn cksumfns[]=
sha256_sum_stream,
sha384_sum_stream,
sha512_sum_stream,
sha2_sum_stream,
sha3_sum_stream,
blake2b_sum_stream,
sm3_sum_stream,
@@ -390,6 +413,7 @@ static digest_output_fn cksum_output_fns[]=
output_file,
output_file,
output_file,
output_file,
};
bool cksum_debug;
#endif
@@ -508,7 +532,7 @@ Print or check %s (%d-bit) checksums.\n\
fputs (_("\
-l, --length=BITS digest length in bits; must not exceed the max size\n\
and must be a multiple of 8 for blake2b;\n\
must be 224, 256, 384, or 512 for sha3\n\
must be 224, 256, 384, or 512 for sha2 or sha3\n\
"), stdout);
# endif
# if HASH_ALGO_CKSUM
@@ -569,10 +593,7 @@ DIGEST determines the digest algorithm and default output format:\n\
crc32b (only available through cksum)\n\
md5 (equivalent to md5sum)\n\
sha1 (equivalent to sha1sum)\n\
sha224 (equivalent to sha224sum)\n\
sha256 (equivalent to sha256sum)\n\
sha384 (equivalent to sha384sum)\n\
sha512 (equivalent to sha512sum)\n\
sha2 (equivalent to sha{224,256,384,512}sum)\n\
sha3 (only available through cksum)\n\
blake2b (equivalent to b2sum)\n\
sm3 (only available through cksum)\n\
@@ -905,17 +926,19 @@ split_3 (char *s, size_t s_len,
#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
/* Auto determine length. */
# if HASH_ALGO_CKSUM
if (cksum_algorithm == blake2b || cksum_algorithm == sha3) {
if (cksum_algorithm == blake2b
|| cksum_algorithm == sha2 || cksum_algorithm == sha3) {
# endif
unsigned char const *hp = *digest;
digest_hex_bytes = 0;
while (c_isxdigit (*hp++))
digest_hex_bytes++;
# if HASH_ALGO_CKSUM
if (cksum_algorithm == sha3 && digest_hex_bytes / 2 != SHA3_224_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA3_256_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA3_384_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA3_512_DIGEST_SIZE)
if ((cksum_algorithm == sha2 || cksum_algorithm == sha3)
&& digest_hex_bytes / 2 != SHA224_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA256_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA384_DIGEST_SIZE
&& digest_hex_bytes / 2 != SHA512_DIGEST_SIZE)
return false;
# endif
if (digest_hex_bytes < 2 || digest_hex_bytes % 2
@@ -1060,7 +1083,8 @@ digest_file (char const *filename, int *binary, unsigned char *bin_result,
fadvise (fp, FADVISE_SEQUENTIAL);
#if HASH_ALGO_CKSUM
if (cksum_algorithm == blake2b || cksum_algorithm == sha3)
if (cksum_algorithm == blake2b
|| cksum_algorithm == sha2 || cksum_algorithm == sha3)
*length = digest_length / 8;
err = DIGEST_STREAM (fp, bin_result, length);
#elif HASH_ALGO_SUM
@@ -1109,6 +1133,11 @@ output_file (char const *file, int binary_file, void const *digest,
if (tagged)
{
# if HASH_ALGO_CKSUM
if (cksum_algorithm == sha2)
printf ("SHA%ju", digest_length);
else
# endif
fputs (DIGEST_TYPE_STRING, stdout);
# if HASH_ALGO_BLAKE2
if (digest_length < DIGEST_MAX_LEN * 8)
@@ -1527,22 +1556,25 @@ main (int argc, char **argv)
min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
# if HASH_ALGO_CKSUM
if (digest_length && (cksum_algorithm != blake2b && cksum_algorithm != sha3))
if (digest_length && (cksum_algorithm != blake2b
&& cksum_algorithm != sha2
&& cksum_algorithm != sha3))
error (EXIT_FAILURE, 0,
_("--length is only supported with --algorithm=blake2b or "
"--algorithm=sha3"));
if (cksum_algorithm == sha3)
_("--length is only supported with --algorithm "
"blake2b, sha2, or sha3"));
if (cksum_algorithm == sha2 || cksum_algorithm == sha3)
{
/* Do not require --length with --check. */
if (digest_length == 0 && *digest_length_str == '\0' && ! do_check)
error (EXIT_FAILURE, 0, _("--algorithm=sha3 requires specifying "
"--length 224, 256, 384, or 512"));
error (EXIT_FAILURE, 0, _("--algorithm=%s requires specifying "
"--length 224, 256, 384, or 512"),
algorithm_args[cksum_algorithm]);
/* If --check and --length are used we verify the digest length. */
if ((! do_check || *digest_length_str != '\0')
&& digest_length != SHA3_224_DIGEST_SIZE * 8
&& digest_length != SHA3_256_DIGEST_SIZE * 8
&& digest_length != SHA3_384_DIGEST_SIZE * 8
&& digest_length != SHA3_512_DIGEST_SIZE * 8)
&& digest_length != SHA224_DIGEST_SIZE * 8
&& digest_length != SHA256_DIGEST_SIZE * 8
&& digest_length != SHA384_DIGEST_SIZE * 8
&& digest_length != SHA512_DIGEST_SIZE * 8)
{
error (0, 0, _("invalid length: %s"), quote (digest_length_str));
error (EXIT_FAILURE, 0, _("digest length for %s must be "

View File

@@ -40,6 +40,15 @@ while read algo prog mode; do
$prog $pmode /dev/null >> out || continue
cksum --untagged $cmode --algorithm=$algo /dev/null > out-c || fail=1
case "$algo" in
sha224|sha256|sha384|sha512)
bits=$(echo "$algo" | cut -c4-)
cksum --algorithm=$algo /dev/null > out-t1 || fail=1
cksum --algorithm=sha2 --length=$bits /dev/null > out-t2 || fail=1
compare out-t1 out-t2 || fail=1 ;;
*) ;;
esac
case "$algo" in
bsd) ;;
sysv) ;;

View File

@@ -32,10 +32,7 @@ my @pairs =
['crc32b', "0 0 f"],
['md5', "1B2M2Y8AsgTpgAmY7PhCfg=="],
['sha1', "2jmj7l5rSw0yVb/vlWAYkK/YBwk="],
['sha224', "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw=="],
['sha256', "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="],
['sha384', "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb"],
['sha512', "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=="],
['sha2', "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg=="],
['sha3', "pp9zzKI6msXItWfcGFp1bpfJghZP4lhZ4NHcwUdcgKYVshI68fX5TBHj6UAsOsVY9QAZnZW20+MBdYWGKB3NJg=="],
['blake2b', "eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg=="],
['sm3', "GrIdg1XPoX+OYRlIMegajyK+yMco/vt0ftA161CCqis="],
@@ -48,8 +45,9 @@ sub fmt ($$) {
$h !~ m{^(sysv|bsd|crc|crc32b)$} and $v = uc($h). " (f) = $v";
# BLAKE2b is inconsistent:
$v =~ s{BLAKE2B}{BLAKE2b};
# Our tests use 'cksum -a sha3 --length=512'.
# Our tests use 'cksum -a sha{2,3} --length=512'.
$v =~ s/^SHA3\b/SHA3-512/;
$v =~ s/^SHA2\b/SHA512/;
return "$v"
}
@@ -58,6 +56,7 @@ my @Tests =
# Ensure that each of the above works with --base64:
(map {my ($h,$v)= @$_; my $o=fmt $h,$v;
(my $opts = $h) =~ s/^sha3$/sha3 --length=512/;
$opts =~ s/^sha2$/sha512/;
[$h, "--base64 -a $opts", {IN=>{f=>''}}, {OUT=>"$o\n"}]} @pairs),
# For each that accepts --check, ensure that works with base64 digests:

View File

@@ -21,11 +21,16 @@ print_ver_ cksum shuf
shuf -i 1-10 > input || framework_failure_
for args in '-a sha384' '-a blake2b' '-a blake2b -l 384' '-a sm3'; do
for args in '-a sha2 -l 384' '-a blake2b' '-a blake2b -l 384' '-a sm3'; do
cksum $args 'input' >> CHECKSUMS || fail=1
done
cksum --strict --check CHECKSUMS || fail=1
# We don't output but do support SHA2-### tagged format
cksum -a sha2 -l 384 input |
sed 's/^SHA/SHA2-/' > sha2-tag.sum || framework_failure_
cksum --check sha2-tag.sum || fail=1
# Ensure leading whitespace and \ ignored
sed 's/^/ \\/' CHECKSUMS | cksum --strict -c || fail=1