diff --git a/sbin/md5/md5.1 b/sbin/md5/md5.1 index a17ef5ae30b7..0a8dc46f3b1f 100644 --- a/sbin/md5/md5.1 +++ b/sbin/md5/md5.1 @@ -1,438 +1,440 @@ .Dd February 13, 2024 .Dt MD5 1 .Os .Sh NAME .Nm md5 , sha1 , sha224 , sha256 , sha384 , .Nm sha512 , sha512t224 , sha512t256 , .Nm rmd160 , skein256 , skein512 , skein1024 , .Nm md5sum , sha1sum , sha224sum , sha256sum , sha384sum , .Nm sha512sum , sha512t224sum , sha512t256sum , .Nm rmd160sum , skein256sum , skein512sum , skein1024sum , .Nm shasum .Nd calculate a message-digest fingerprint (checksum) for a file .Sh SYNOPSIS .Nm .Op Fl pqrtx .Op Fl c Ar string .Op Fl s Ar string .Op Ar .Pp .Nm md5sum .Op Fl bctwz .Op Fl -binary .Op Fl -check .Op Fl -help .Op Fl -ignore-missing .Op Fl -quiet .Op Fl -status .Op Fl -strict .Op Fl -tag .Op Fl -text .Op Fl -version .Op Fl -warn .Op Fl -zero .Op Ar .Pp (All other hashes have the same options and usage.) .Pp .Nm shasum .Op Fl 0bchqstUvw .Op Fl -01 .Op Fl a | -algorithm Ar alg .Op Fl -binary .Op Fl -check .Op Fl -help .Op Fl -ignore-missing .Op Fl -quiet .Op Fl -status .Op Fl -strict .Op Fl -tag .Op Fl -text .Op Fl -UNIVERSAL .Op Fl -version .Op Fl -warn .Op Ar .Sh DESCRIPTION The .Nm md5 , sha1 , sha224 , sha256 , sha384 , sha512 , sha512t224 , sha512t256 , .Nm rmd160 , skein256 , skein512 , and .Nm skein1024 utilities take as input a message of arbitrary length and produce as output a .Dq fingerprint or .Dq message digest of the input. .Pp The .Nm md5sum , sha1sum , sha224sum , sha256sum , sha384sum , sha512sum , .Nm sha512t224sum , sha512t256sum , rmd160sum , skein256sum , skein512sum , and .Nm skein1024sum utilities do the same, but with command-line options and an output format that match those of their similary named GNU utilities. .Pp The .Nm shasum utility does the same, but with command-line options and an output format that match those of the similarly named utility that ships with Perl. .Pp In all cases, each file listed on the command line is processed separately. If no files are listed on the command line, or a file name is given as .Pa - , input is taken from stdin instead. .Pp It is conjectured that it is computationally infeasible to produce two messages having the same message digest, or to produce any message having a given prespecified target message digest. The SHA-224 , SHA-256 , SHA-384 , SHA-512, RIPEMD-160, and SKEIN algorithms are intended for digital signature applications, where a large file must be .Dq compressed in a secure manner before being encrypted with a private (secret) key under a public-key cryptosystem such as RSA. .Pp The MD5 and SHA-1 algorithms have been proven to be vulnerable to practical collision attacks and should not be relied upon to produce unique outputs, .Em nor should they be used as part of a cryptographic signature scheme. As of 2017-03-02, there is no publicly known method to .Em reverse either algorithm, i.e., to find an input that produces a specific output. .Pp SHA-512t256 is a version of SHA-512 truncated to only 256 bits. On 64-bit hardware, this algorithm is approximately 50% faster than SHA-256 but with the same level of security. The hashes are not interchangeable. .Pp SHA-512t224 is identical to SHA-512t256, but with the digest truncated to 224 bits. .Pp It is recommended that all new applications use SHA-512 or SKEIN-512 instead of one of the other hash functions. .Ss BSD OPTIONS The following options are available in BSD mode, i.e. when the program is invoked with a name that does not end in .Dq sum : .Bl -tag -width indent .It Fl c Ar string , Fl -check= Ns Ar string Compare the digest of the file against this string. If combined with the .Fl q or .Fl -quiet option, the calculated digest is printed in addition to the exit status being set. .Pq Note that this option is not yet useful if multiple files are specified. .It Fl p , -passthrough Echo stdin to stdout and append the checksum to stdout. +In this mode, any files specified on the command line are silently ignored. .It Fl q , -quiet Quiet mode \(em only the checksum is printed out. Overrides the .Fl r or .Fl -reverse option. .It Fl r , -reverse Reverses the format of the output. This helps with visual diffs. Does nothing when combined with the .Fl ptx options. .It Fl s Ar string , Fl -string= Ns Ar string Print a checksum of the given .Ar string . +In this mode, any files specified on the command line are silently ignored. .It Fl t , Fl -time-trial Run a built-in time trial. For the .Nm -sum versions, this is a nop for compatibility with coreutils. .It Fl x , Fl -self-test Run a built-in test script. .El .Ss GNU OPTIONS The following options are available in GNU mode, i.e. when the program is invoked with a name that ends in .Dq sum : .Bl -tag -width indent .It Fl b , Fl -binary Read files in binary mode. .It Fl c , Fl -check The file passed as arguments must contain digest lines generated by the same digest algorithm in either classical BSD format or in GNU coreutils format. A line with the file name followed by a colon .Dq ":" and either OK or FAILED is written for each well-formed line in the digest file. If applicable, the number of failed comparisons and the number of lines that were skipped since they were not well-formed are printed at the end. The .Fl -quiet option can be used to quiesce the output unless there are mismatched entries in the digest. .It Fl -help Print a usage message and exit. .It Fl -ignore-missing When verifying checksums, ignore files for which checksums are given but which aren't found on disk. .It Fl -quiet When verifying checksums, do not print anything unless the verification fails. .It Fl -status When verifying checksums, do not print anything at all. The exit code will reflect whether verification succeeded. .It Fl -strict When verifying checksums, fail if the input is malformed. .It Fl -tag Produce BSD-style output. .It Fl t , Fl -text Read files in text mode. This is the default. Note that this implementation does not differentiate between binary and text mode. .It Fl -version Print version information and exit. .It Fl w , Fl -warn When verifying checksums, warn about malformed input. .It Fl z , Fl -zero Terminate output lines with NUL rather than with newline. .El .Ss PERL OPTIONS The following options are available in Perl mode, i.e. when the program is invoked with the name .Dq shasum : .Bl -tag -width indent .It Fl 0 , Fl -01 Read files in bits mode: ASCII .Sq 0 and .Sq 1 characters correspond to 0 and 1 bits, respectively, and all other characters are ignored. See .Sx BUGS . .It Fl a Ar alg , Fl -algorithm Ar alg Use the specified algorithm: .Dq 1 for SHA-1 (default), .Dq xxx for .Va xxx Ns -bit SHA-2 (e.g. .Dq 256 for SHA-256) or .Dq xxxyyy for .Va xxx Ns -bit SHA-2 truncated to .Va yyy bits (e.g. .Dq 512224 for SHA-512/224). .It Fl b , Fl -binary Read files in binary mode. .It Fl c , Fl -check The file passed as arguments must contain digest lines generated by the same digest algorithm in either classical BSD format or in GNU coreutils format. A line with the file name followed by a colon .Dq ":" and either OK or FAILED is written for each well-formed line in the digest file. If applicable, the number of failed comparisons and the number of lines that were skipped since they were not well-formed are printed at the end. The .Fl -quiet option can be used to quiesce the output unless there are mismatched entries in the digest. .It Fl -help Print a usage message and exit. .It Fl -ignore-missing When verifying checksums, ignore files for which checksums are given but which aren't found on disk. .It Fl -quiet When verifying checksums, do not print anything unless the verification fails. .It Fl -status When verifying checksums, do not print anything at all. The exit code will reflect whether verification succeeded. .It Fl -strict When verifying checksums, fail if the input is malformed. .It Fl -tag Produce BSD-style output. .It Fl t , Fl -text Read files in text mode. This is the default. Note that this implementation does not differentiate between binary and text mode. .It Fl U , Fl -UNIVERSAL Read files in universal mode: any CR-LF pair, as well as any CR not followed by LF, is translated to LF before the digest is computed. .It Fl -version Print version information and exit. .It Fl w , Fl -warn When verifying checksums, warn about malformed input. .El .Sh EXIT STATUS The .Nm md5 , sha1 , sha224 , sha256 , sha384 , sha512 , .Nm sha512t224 , sha512t256 , .Nm rmd160 , skein256 , skein512 , and .Nm skein1024 utilities exit 0 on success, 1 if at least one of the input files could not be read, and 2 if at least one file does not have the same hash as the .Fl c option. .Pp The .Nm md5sum , sha1sum , sha224sum , sha256sum , sha384sum , sha512sum , .Nm sha512t224sum , sha512t256sum , .Nm rmd160 , skein256 , skein512 , skein1024 and .Nm shasum utilities exit 0 on success and 1 if at least one of the input files could not be read or, when verifying checksums, does not have the expected checksum. .Sh EXAMPLES Calculate the MD5 checksum of the string .Dq Hello . .Bd -literal -offset indent $ md5 -s Hello MD5 ("Hello") = 8b1a9953c4611296a827abf8c47804d7 .Ed .Pp Same as above, but note the absence of the newline character in the input string: .Bd -literal -offset indent $ echo -n Hello | md5 8b1a9953c4611296a827abf8c47804d7 .Ed .Pp Calculate the checksum of multiple files reversing the output: .Bd -literal -offset indent $ md5 -r /boot/loader.conf /etc/rc.conf ada5f60f23af88ff95b8091d6d67bef6 /boot/loader.conf d80bf36c332dc0fdc479366ec3fa44cd /etc/rc.conf .Ed .Pp This is almost but not quite identical to the output from GNU mode: .Bd -literal -offset indent $ md5sum /boot/loader.conf /etc/rc.conf ada5f60f23af88ff95b8091d6d67bef6 /boot/loader.conf d80bf36c332dc0fdc479366ec3fa44cd /etc/rc.conf .Ed .Pp Note the two spaces between hash and file name. If binary mode is requested, they are instead separated by a space and an asterisk: .Bd -literal -offset indent $ md5sum -b /boot/loader.conf /etc/rc.conf ada5f60f23af88ff95b8091d6d67bef6 */boot/loader.conf d80bf36c332dc0fdc479366ec3fa44cd */etc/rc.conf .Ed .Pp Write the digest for .Pa /boot/loader.conf in a file named .Pa digest . Then calculate the checksum again and validate it against the checksum string extracted from the .Pa digest file: .Bd -literal -offset indent $ md5 /boot/loader.conf > digest && md5 -c $(cut -f2 -d= digest) /boot/loader.conf MD5 (/boot/loader.conf) = ada5f60f23af88ff95b8091d6d67bef6 .Ed .Pp Same as above but comparing the digest against an invalid string .Pq Dq randomstring , which results in a failure. .Bd -literal -offset indent $ md5 -c randomstring /boot/loader.conf MD5 (/boot/loader.conf) = ada5f60f23af88ff95b8091d6d67bef6 [ Failed ] .Ed .Pp In GNU mode, the .Fl c option does not compare against a hash string passed as parameter. Instead, it expects a digest file, as created under the name .Pa digest for .Pa /boot/loader.conf in the example above. .Bd -literal -offset indent $ md5 -c digest /boot/loader.conf /boot/loader.conf: OK .Ed .Pp The digest file may contain any number of lines in the format generated in either BSD or GNU mode. If a hash value does not match the file, .Dq FAILED is printed instead of .Dq OK . .Sh SEE ALSO .Xr cksum 1 , .Xr md5 3 , .Xr ripemd 3 , .Xr sha 3 , .Xr sha256 3 , .Xr sha384 3 , .Xr sha512 3 , .Xr skein 3 .Rs .%A R. Rivest .%T The MD5 Message-Digest Algorithm .%O RFC1321 .Re .Rs .%A J. Burrows .%T The Secure Hash Standard .%O FIPS PUB 180-2 .Re .Rs .%A D. Eastlake and P. Jones .%T US Secure Hash Algorithm 1 .%O RFC 3174 .Re .Pp RIPEMD-160 is part of the ISO draft standard .Qq ISO/IEC DIS 10118-3 on dedicated hash functions. .Pp Secure Hash Standard (SHS): .Pa https://www.nist.gov/publications/secure-hash-standard-shs .Pp The RIPEMD-160 page: .Pa https://homes.esat.kuleuven.be/~bosselae/ripemd160.html .Sh BUGS In bits mode, the original .Nm shasum script is capable of processing inputs of arbitrary length. This implementation is not, and will issue an error if the input length is not a multiple of eight bits. .Sh ACKNOWLEDGMENTS .An -nosplit This utility was originally derived from a program which was placed in the public domain for free general use by RSA Data Security. .Pp Support for SHA-1 and RIPEMD-160 was added by .An Oliver Eikemeier Aq Mt eik@FreeBSD.org . .Pp Support for SHA-2 was added by .An Colin Percival Aq Mt cperciva@FreeBSD.org and .An Allan Jude Aq Mt allanjude@FreeBSD.org . .Pp Support for SKEIN was added by .An Allan Jude Aq Mt allanjude@FreeBSD.org . .Pp Compatibility with GNU coreutils was added by .An Warner Losh Aq Mt imp@FreeBSD.org and much expanded by .An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org , who also added Perl compatibility. diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c index 29f212148ce3..2045b623ff57 100644 --- a/sbin/md5/md5.c +++ b/sbin/md5/md5.c @@ -1,1047 +1,1047 @@ /* * Derived from: * * MDDRIVER.C - test driver for MD2, MD4 and MD5 */ /* * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All * rights reserved. * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CAPSICUM #include #include #include #include #endif /* * Length of test block, number of test blocks. */ #define TEST_BLOCK_LEN 10000 #define TEST_BLOCK_COUNT 100000 #define MDTESTCOUNT 8 static char *progname; static bool cflag; static bool pflag; static bool qflag; static bool sflag; static bool wflag; static bool strict; static bool skip; static bool ignoreMissing; static char* checkAgainst; static int checksFailed; static bool failed; static int endl = '\n'; typedef void (DIGEST_Init)(void *); typedef void (DIGEST_Update)(void *, const unsigned char *, size_t); typedef char *(DIGEST_End)(void *, char *); extern const char *MD5TestOutput[MDTESTCOUNT]; extern const char *SHA1_TestOutput[MDTESTCOUNT]; extern const char *SHA224_TestOutput[MDTESTCOUNT]; extern const char *SHA256_TestOutput[MDTESTCOUNT]; extern const char *SHA384_TestOutput[MDTESTCOUNT]; extern const char *SHA512_TestOutput[MDTESTCOUNT]; extern const char *SHA512t224_TestOutput[MDTESTCOUNT]; extern const char *SHA512t256_TestOutput[MDTESTCOUNT]; extern const char *RIPEMD160_TestOutput[MDTESTCOUNT]; extern const char *SKEIN256_TestOutput[MDTESTCOUNT]; extern const char *SKEIN512_TestOutput[MDTESTCOUNT]; extern const char *SKEIN1024_TestOutput[MDTESTCOUNT]; typedef struct Algorithm_t { const char *progname; const char *perlname; const char *name; const char *(*TestOutput)[MDTESTCOUNT]; DIGEST_Init *Init; DIGEST_Update *Update; DIGEST_End *End; char *(*Data)(const void *, unsigned int, char *); } Algorithm_t; static void MD5_Update(MD5_CTX *, const unsigned char *, size_t); static char *MDInput(const Algorithm_t *, FILE *, char *, bool); static void MDOutput(const Algorithm_t *, char *, const char *); static void MDTimeTrial(const Algorithm_t *); static void MDTestSuite(const Algorithm_t *); static void usage(const Algorithm_t *); static void version(void); typedef union { MD5_CTX md5; SHA1_CTX sha1; SHA224_CTX sha224; SHA256_CTX sha256; SHA384_CTX sha384; SHA512_CTX sha512; RIPEMD160_CTX ripemd160; SKEIN256_CTX skein256; SKEIN512_CTX skein512; SKEIN1024_CTX skein1024; } DIGEST_CTX; /* max(MD5_DIGEST_LENGTH, SHA_DIGEST_LENGTH, SHA256_DIGEST_LENGTH, SHA512_DIGEST_LENGTH, RIPEMD160_DIGEST_LENGTH, SKEIN1024_DIGEST_LENGTH)*2+1 */ #define HEX_DIGEST_LENGTH 257 /* algorithm function table */ static const struct Algorithm_t Algorithm[] = { { "md5", NULL, "MD5", &MD5TestOutput, (DIGEST_Init*)&MD5Init, (DIGEST_Update*)&MD5_Update, (DIGEST_End*)&MD5End, &MD5Data }, { "sha1", "1", "SHA1", &SHA1_TestOutput, (DIGEST_Init*)&SHA1_Init, (DIGEST_Update*)&SHA1_Update, (DIGEST_End*)&SHA1_End, &SHA1_Data }, { "sha224", "224", "SHA224", &SHA224_TestOutput, (DIGEST_Init*)&SHA224_Init, (DIGEST_Update*)&SHA224_Update, (DIGEST_End*)&SHA224_End, &SHA224_Data }, { "sha256", "256", "SHA256", &SHA256_TestOutput, (DIGEST_Init*)&SHA256_Init, (DIGEST_Update*)&SHA256_Update, (DIGEST_End*)&SHA256_End, &SHA256_Data }, { "sha384", "384", "SHA384", &SHA384_TestOutput, (DIGEST_Init*)&SHA384_Init, (DIGEST_Update*)&SHA384_Update, (DIGEST_End*)&SHA384_End, &SHA384_Data }, { "sha512", "512", "SHA512", &SHA512_TestOutput, (DIGEST_Init*)&SHA512_Init, (DIGEST_Update*)&SHA512_Update, (DIGEST_End*)&SHA512_End, &SHA512_Data }, { "sha512t224", "512224", "SHA512t224", &SHA512t224_TestOutput, (DIGEST_Init*)&SHA512_224_Init, (DIGEST_Update*)&SHA512_224_Update, (DIGEST_End*)&SHA512_224_End, &SHA512_224_Data }, { "sha512t256", "512256", "SHA512t256", &SHA512t256_TestOutput, (DIGEST_Init*)&SHA512_256_Init, (DIGEST_Update*)&SHA512_256_Update, (DIGEST_End*)&SHA512_256_End, &SHA512_256_Data }, { "rmd160", NULL, "RMD160", &RIPEMD160_TestOutput, (DIGEST_Init*)&RIPEMD160_Init, (DIGEST_Update*)&RIPEMD160_Update, (DIGEST_End*)&RIPEMD160_End, &RIPEMD160_Data }, { "skein256", NULL, "Skein256", &SKEIN256_TestOutput, (DIGEST_Init*)&SKEIN256_Init, (DIGEST_Update*)&SKEIN256_Update, (DIGEST_End*)&SKEIN256_End, &SKEIN256_Data }, { "skein512", NULL, "Skein512", &SKEIN512_TestOutput, (DIGEST_Init*)&SKEIN512_Init, (DIGEST_Update*)&SKEIN512_Update, (DIGEST_End*)&SKEIN512_End, &SKEIN512_Data }, { "skein1024", NULL, "Skein1024", &SKEIN1024_TestOutput, (DIGEST_Init*)&SKEIN1024_Init, (DIGEST_Update*)&SKEIN1024_Update, (DIGEST_End*)&SKEIN1024_End, &SKEIN1024_Data }, { } }; static int digest = -1; static unsigned int malformed; static enum mode { mode_bsd, mode_gnu, mode_perl, } mode = mode_bsd; static enum input_mode { input_binary = '*', input_text = ' ', input_universal = 'U', input_bits = '^', } input_mode = input_binary; static enum output_mode { output_bare, output_tagged, output_reverse, output_gnu, } output_mode = output_tagged; enum optval { opt_end = -1, /* ensure we don't collide with shortopts */ opt_dummy = CHAR_MAX, /* BSD options */ opt_check, opt_passthrough, opt_quiet, opt_reverse, opt_string, opt_time_trial, opt_self_test, /* GNU options */ opt_binary, opt_help, opt_ignore_missing, opt_status, opt_strict, opt_tag, opt_text, opt_warn, opt_version, opt_zero, /* Perl options */ opt_algorithm, opt_bits, opt_universal, }; static const struct option bsd_longopts[] = { { "check", required_argument, 0, opt_check }, { "passthrough", no_argument, 0, opt_passthrough }, { "quiet", no_argument, 0, opt_quiet }, { "reverse", no_argument, 0, opt_reverse }, { "string", required_argument, 0, opt_string }, { "time-trial", no_argument, 0, opt_time_trial }, { "self-test", no_argument, 0, opt_self_test }, { } }; static const char *bsd_shortopts = "bc:pqrs:tx"; static const struct option gnu_longopts[] = { { "binary", no_argument, 0, opt_binary }, { "check", no_argument, 0, opt_check }, { "help", no_argument, 0, opt_help }, { "ignore-missing", no_argument, 0, opt_ignore_missing }, { "quiet", no_argument, 0, opt_quiet }, { "status", no_argument, 0, opt_status }, { "strict", no_argument, 0, opt_strict }, { "tag", no_argument, 0, opt_tag }, { "text", no_argument, 0, opt_text }, { "version", no_argument, 0, opt_version }, { "warn", no_argument, 0, opt_warn }, { "zero", no_argument, 0, opt_zero }, { } }; static const char *gnu_shortopts = "bctwz"; static const struct option perl_longopts[] = { { "algorithm", required_argument, 0, opt_algorithm }, { "check", required_argument, 0, opt_check }, { "help", no_argument, 0, opt_help }, { "ignore-missing", no_argument, 0, opt_ignore_missing }, { "quiet", no_argument, 0, opt_quiet }, { "status", no_argument, 0, opt_status }, { "strict", no_argument, 0, opt_strict }, { "tag", no_argument, 0, opt_tag }, { "text", no_argument, 0, opt_text }, { "UNIVERSAL", no_argument, 0, opt_universal }, { "version", no_argument, 0, opt_version }, { "warn", no_argument, 0, opt_warn }, { "01", no_argument, 0, opt_bits }, { } }; static const char *perl_shortopts = "0a:bchqstUvw"; static void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len) { MD5Update(c, data, len); } struct chksumrec { char *filename; char *chksum; struct chksumrec *next; }; static struct chksumrec *head = NULL; static struct chksumrec **next = &head; static unsigned int numrecs; #define PADDING 7 /* extra padding for "SHA512t256 (...) = ...\n" style */ #define CHKFILELINELEN (HEX_DIGEST_LENGTH + MAXPATHLEN + PADDING) static void gnu_check(const char *checksumsfile) { FILE *inp; char *linebuf = NULL; size_t linecap; ssize_t linelen; int lineno; char *filename; char *hashstr; struct chksumrec *rec; const char *digestname; size_t digestnamelen; size_t hashstrlen; struct stat st; if (strcmp(checksumsfile, "-") == 0) inp = stdin; else if ((inp = fopen(checksumsfile, "r")) == NULL) err(1, "%s", checksumsfile); digestname = Algorithm[digest].name; digestnamelen = strlen(digestname); hashstrlen = strlen(*(Algorithm[digest].TestOutput[0])); lineno = 0; linecap = CHKFILELINELEN; while ((linelen = getline(&linebuf, &linecap, inp)) > 0) { lineno++; while (linelen > 0 && linebuf[linelen - 1] == '\n') linelen--; linebuf[linelen] = '\0'; filename = linebuf + digestnamelen + 2; hashstr = linebuf + linelen - hashstrlen; /* * supported formats: * BSD: (): * GNU: [ *U^] */ if ((size_t)linelen >= digestnamelen + hashstrlen + 6 && strncmp(linebuf, digestname, digestnamelen) == 0 && strncmp(filename - 2, " (", 2) == 0 && strncmp(hashstr - 4, ") = ", 4) == 0 && strspn(hashstr, "0123456789ABCDEFabcdef") == hashstrlen) { *(hashstr - 4) = '\0'; } else if ((size_t)linelen >= hashstrlen + 3 && strspn(linebuf, "0123456789ABCDEFabcdef") == hashstrlen && linebuf[hashstrlen] == ' ') { linebuf[hashstrlen] = '\0'; hashstr = linebuf; filename = linebuf + hashstrlen + 1; } else { if (wflag) { warnx("%s: %d: improperly formatted " "%s checksum line", checksumsfile, lineno, mode == mode_perl ? "SHA" : digestname); } malformed++; continue; } rec = malloc(sizeof(*rec)); if (rec == NULL) errx(1, "malloc failed"); if (*filename == '*' || *filename == ' ' || *filename == 'U' || *filename == '^') { if (lstat(filename, &st) != 0) filename++; } rec->chksum = strdup(hashstr); rec->filename = strdup(filename); if (rec->chksum == NULL || rec->filename == NULL) errx(1, "malloc failed"); rec->next = NULL; *next = rec; next = &rec->next; numrecs++; } if (inp != stdin) fclose(inp); } /* Main driver. Arguments (may be any combination): -sstring - digests string -t - runs time trial -x - runs test script filename - digests file (none) - digests standard input */ int main(int argc, char *argv[]) { #ifdef HAVE_CAPSICUM cap_rights_t rights; fileargs_t *fa = NULL; #endif const struct option *longopts; const char *shortopts; FILE *f; int i, opt; char *p, *string = NULL; char buf[HEX_DIGEST_LENGTH]; size_t len; struct chksumrec *rec; if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else progname++; /* * GNU coreutils has a number of programs named *sum. These produce * similar results to the BSD version, but in a different format, * similar to BSD's -r flag. We install links to this program with * ending 'sum' to provide this compatibility. Check here to see if the * name of the program ends in 'sum', set the flag and drop the 'sum' so * the digest lookup works. Also, make -t a nop when running in this mode * since that means 'text file' there (though it's a nop in coreutils * on unix-like systems). The -c flag conflicts, so it's just disabled * in this mode (though in the future it might be implemented). * * We also strive to be compatible with the shasum script which is * included in Perl. It is roughly equivalent to the GNU offering * but uses a command-line argument to select the algorithm, and * supports only SHA-1 and SHA-2. */ len = strlen(progname); if (strcmp(progname, "shasum") == 0) { mode = mode_perl; input_mode = input_text; output_mode = output_gnu; digest = 1; longopts = perl_longopts; shortopts = perl_shortopts; } else if (len > 3 && strcmp(progname + len - 3, "sum") == 0) { len -= 3; mode = mode_gnu; input_mode = input_text; /* * The historical behavior in GNU emulation mode is * output_reverse, however this not true to the original * and the flag that was used to force the correct output * was -b, which means something else (input_binary) in * GNU land. Switch to the correct behavior. */ output_mode = output_gnu; longopts = gnu_longopts; shortopts = gnu_shortopts; } else { mode = mode_bsd; input_mode = input_binary; output_mode = output_tagged; longopts = bsd_longopts; shortopts = bsd_shortopts; } if (digest < 0) { for (digest = 0; Algorithm[digest].progname != NULL; digest++) if (strncasecmp(Algorithm[digest].progname, progname, len) == 0) break; if (Algorithm[digest].progname == NULL) digest = 0; } failed = false; checkAgainst = NULL; checksFailed = 0; skip = false; while ((opt = getopt_long(argc, argv, shortopts, longopts, NULL)) != opt_end) switch (opt) { case opt_bits: case '0': input_mode = input_bits; break; case opt_algorithm: case 'a': for (i = 0; Algorithm[i].progname != NULL; i++) { if (Algorithm[i].perlname != NULL && strcasecmp(Algorithm[i].perlname, optarg) == 0) { digest = i; break; } } if (Algorithm[i].progname == NULL) usage(&Algorithm[digest]); break; case opt_binary: case 'b': /* in BSD mode, -b is now a no-op */ if (mode != mode_bsd) input_mode = input_binary; break; case opt_check: case 'c': cflag = true; if (mode == mode_bsd) checkAgainst = optarg; break; case opt_passthrough: case 'p': pflag = true; break; case opt_quiet: case 'q': output_mode = output_bare; qflag = true; break; case opt_reverse: case 'r': if (!qflag) output_mode = output_reverse; break; case opt_status: sflag = true; break; case opt_strict: strict = 1; break; case 's': if (mode == mode_perl) { sflag = true; break; } /* fall through */ case opt_string: output_mode = output_bare; string = optarg; break; case opt_tag: output_mode = output_tagged; break; case opt_time_trial: case opt_text: case 't': if (mode == mode_bsd) { MDTimeTrial(&Algorithm[digest]); skip = true; } else { input_mode = input_text; } break; case opt_universal: case 'U': input_mode = input_universal; break; case opt_version: version(); break; case opt_warn: case 'w': wflag = true; break; case opt_self_test: case 'x': MDTestSuite(&Algorithm[digest]); skip = true; break; case opt_zero: case 'z': endl = '\0'; break; case opt_ignore_missing: ignoreMissing = true; break; default: usage(&Algorithm[digest]); } argc -= optind; argv += optind; #ifdef HAVE_CAPSICUM if (caph_limit_stdout() < 0 || caph_limit_stderr() < 0) err(1, "unable to limit rights for stdio"); #endif if (cflag && mode != mode_bsd) { /* * Read digest files into a linked list, then replace argv * with an array of the filenames from that list. */ if (argc < 1) usage(&Algorithm[digest]); while (argc--) gnu_check(*argv++); argc = 0; argv = calloc(sizeof(char *), numrecs + 1); for (rec = head; rec != NULL; rec = rec->next) { argv[argc] = rec->filename; argc++; } argv[argc] = NULL; rec = head; } #ifdef HAVE_CAPSICUM fa = fileargs_init(argc, argv, O_RDONLY, 0, cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_FCNTL), FA_OPEN | FA_LSTAT); if (fa == NULL) err(1, "Unable to initialize casper"); if (caph_enter_casper() < 0) err(1, "Unable to enter capability mode"); #endif - if (*argv) { + if (*argv && !pflag && string == NULL) { do { const char *filename = *argv; const char *filemode = "rb"; if (strcmp(filename, "-") == 0) { f = stdin; } else { #ifdef HAVE_CAPSICUM f = fileargs_fopen(fa, filename, filemode); #else f = fopen(filename, filemode); #endif } if (f == NULL) { if (errno != ENOENT || !(cflag && ignoreMissing)) { warn("%s", filename); failed = true; } if (cflag && mode != mode_bsd) rec = rec->next; continue; } #ifdef HAVE_CAPSICUM if (caph_rights_limit(fileno(f), &rights) < 0) err(1, "capsicum"); #endif if (cflag && mode != mode_bsd) { checkAgainst = rec->chksum; rec = rec->next; } p = MDInput(&Algorithm[digest], f, buf, false); if (f != stdin) (void)fclose(f); MDOutput(&Algorithm[digest], p, filename); } while (*++argv); } else if (!cflag && string == NULL && !skip) { #ifdef HAVE_CAPSICUM if (caph_limit_stdin() < 0) err(1, "capsicum"); #endif if (mode == mode_bsd) output_mode = output_bare; p = MDInput(&Algorithm[digest], stdin, buf, pflag); MDOutput(&Algorithm[digest], p, "-"); } else if (string != NULL) { len = strlen(string); p = Algorithm[digest].Data(string, len, buf); MDOutput(&Algorithm[digest], p, string); } if (cflag && mode != mode_bsd) { if (!sflag && malformed > 1) warnx("WARNING: %d lines are improperly formatted", malformed); else if (!sflag && malformed > 0) warnx("WARNING: %d line is improperly formatted", malformed); if (!sflag && checksFailed > 1) warnx("WARNING: %d computed checksums did NOT match", checksFailed); else if (!sflag && checksFailed > 0) warnx("WARNING: %d computed checksum did NOT match", checksFailed); if (checksFailed != 0 || (strict && malformed > 0)) return (1); } #ifdef HAVE_CAPSICUM fileargs_free(fa); #endif if (failed) return (1); if (checksFailed > 0) return (2); return (0); } /* * Common input handling */ static char * MDInput(const Algorithm_t *alg, FILE *f, char *buf, bool tee) { char block[4096]; DIGEST_CTX context; char *end, *p, *q; size_t len; int bits; uint8_t byte; bool cr = false; alg->Init(&context); while ((len = fread(block, 1, sizeof(block), f)) > 0) { switch (input_mode) { case input_binary: case input_text: if (tee && fwrite(block, 1, len, stdout) != len) err(1, "stdout"); alg->Update(&context, block, len); break; case input_universal: end = block + len; for (p = q = block; p < end; p = q) { if (cr) { if (*p == '\n') p++; if (tee && putchar('\n') == EOF) err(1, "stdout"); alg->Update(&context, "\n", 1); cr = false; } for (q = p; q < end && *q != '\r'; q++) /* nothing */; if (q > p) { if (tee && fwrite(p, 1, q - p, stdout) != (size_t)(q - p)) err(1, "stdout"); alg->Update(&context, p, q - p); } if (q < end && *q == '\r') { cr = true; q++; } } break; case input_bits: end = block + len; bits = byte = 0; for (p = block; p < end; p++) { if (*p == '0' || *p == '1') { byte <<= 1; byte |= *p - '0'; if (++bits == 8) { if (tee && putchar(byte) == EOF) err(1, "stdout"); alg->Update(&context, &byte, 1); bits = byte = 0; } } } break; } } if (ferror(f)) { alg->End(&context, buf); return (NULL); } if (cr) { if (tee && putchar('\n') == EOF) err(1, "stdout"); alg->Update(&context, "\n", 1); } if (input_mode == input_bits && bits != 0) errx(1, "input length was not a multiple of 8"); return (alg->End(&context, buf)); } /* * Common output handling */ static void MDOutput(const Algorithm_t *alg, char *p, const char *name) { bool checkfailed = false; if (p == NULL) { warn("%s", name); failed = true; } else if (cflag && mode != mode_bsd) { checkfailed = strcasecmp(checkAgainst, p) != 0; if (!sflag && (!qflag || checkfailed)) printf("%s: %s%c", name, checkfailed ? "FAILED" : "OK", endl); } else { switch (output_mode) { case output_bare: printf("%s", p); break; case output_gnu: printf("%s %c%s", p, input_mode, name); break; case output_reverse: printf("%s %s", p, name); break; case output_tagged: if (mode == mode_perl && strncmp(alg->name, "SHA512t", 7) == 0) { printf("%.6s/%s", alg->name, alg->name + 7); } else { printf("%s", alg->name); } printf(" (%s) = %s", name, p); break; } if (checkAgainst) { checkfailed = strcasecmp(checkAgainst, p) != 0; if (!qflag && checkfailed) printf(" [ Failed ]"); } printf("%c", endl); } if (checkfailed) checksFailed++; } /* * Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. */ static void MDTimeTrial(const Algorithm_t *alg) { DIGEST_CTX context; struct rusage before, after; struct timeval total; float seconds; unsigned char block[TEST_BLOCK_LEN]; unsigned int i; char *p, buf[HEX_DIGEST_LENGTH]; printf("%s time trial. Digesting %d %d-byte blocks ...", alg->name, TEST_BLOCK_COUNT, TEST_BLOCK_LEN); fflush(stdout); /* Initialize block */ for (i = 0; i < TEST_BLOCK_LEN; i++) block[i] = (unsigned char) (i & 0xff); /* Start timer */ getrusage(RUSAGE_SELF, &before); /* Digest blocks */ alg->Init(&context); for (i = 0; i < TEST_BLOCK_COUNT; i++) alg->Update(&context, block, TEST_BLOCK_LEN); p = alg->End(&context, buf); /* Stop timer */ getrusage(RUSAGE_SELF, &after); timersub(&after.ru_utime, &before.ru_utime, &total); seconds = total.tv_sec + (float) total.tv_usec / 1000000; printf(" done\n"); printf("Digest = %s", p); printf("\nTime = %f seconds\n", seconds); printf("Speed = %f MiB/second\n", (float) TEST_BLOCK_LEN * (float) TEST_BLOCK_COUNT / seconds / (1 << 20)); } /* * Digests a reference suite of strings and prints the results. */ static const char *MDTestInput[MDTESTCOUNT] = { "", "a", "abc", "message digest", "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "MD5 has not yet (2001-09-03) been broken, but sufficient attacks have been made \ that its security is in some doubt" }; const char *MD5TestOutput[MDTESTCOUNT] = { "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f", "57edf4a22be3c955ac49da2e2107b67a", "b50663f41d44d92171cb9976bc118538" }; const char *SHA1_TestOutput[MDTESTCOUNT] = { "da39a3ee5e6b4b0d3255bfef95601890afd80709", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a9993e364706816aba3e25717850c26c9cd0d89d", "c12252ceda8be8994d5fa0290a47231c1d16aae3", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89", "761c457bf73b14d27e9e9265c46f4b4dda11f940", "50abf5706a150990a08b2c5ea40fa0e585554732", "18eca4333979c4181199b7b4fab8786d16cf2846" }; const char *SHA224_TestOutput[MDTESTCOUNT] = { "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb", "45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2", "bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9", "b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e", "5ae55f3779c8a1204210d7ed7689f661fbe140f96f272ab79e19d470" }; const char *SHA256_TestOutput[MDTESTCOUNT] = { "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650", "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73", "db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0", "f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e", "e6eae09f10ad4122a0e2a4075761d185a272ebd9f5aa489e998ff2f09cbfdd9f" }; const char *SHA384_TestOutput[MDTESTCOUNT] = { "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5", "feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4", "1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84", "b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026", "99428d401bf4abcd4ee0695248c9858b7503853acfae21a9cffa7855f46d1395ef38596fcd06d5a8c32d41a839cc5dfb" }; const char *SHA512_TestOutput[MDTESTCOUNT] = { "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c", "4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1", "1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894", "72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843", "e8a835195e039708b13d9131e025f4441dbdc521ce625f245a436dcd762f54bf5cb298d96235e6c6a304e087ec8189b9512cbdf6427737ea82793460c367b9c3" }; const char *SHA512t224_TestOutput[MDTESTCOUNT] = { "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327", "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa", "ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564", "ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8", "a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3", "ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2", "b3c3b945249b0c8c94aba76ea887bcaad5401665a1fbeb384af4d06b" }; const char *SHA512t256_TestOutput[MDTESTCOUNT] = { "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8", "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23", "0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb", "fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26", "cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8", "2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148", "dd095fc859b336c30a52548b3dc59fcc0d1be8616ebcf3368fad23107db2d736" }; const char *RIPEMD160_TestOutput[MDTESTCOUNT] = { "9c1185a5c5e9fc54612808977ee8f548b2258d31", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "5d0689ef49d2fae572b881b123a85ffa21595f36", "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "b0e20b6e3116640286ed3a87a5713079b21f5189", "9b752e45573d4b39f4dbd3323cab82bf63326bfb", "5feb69c6bf7c29d95715ad55f57d8ac5b2b7dd32" }; const char *SKEIN256_TestOutput[MDTESTCOUNT] = { "c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba", "7fba44ff1a31d71a0c1f82e6e82fb5e9ac6c92a39c9185b9951fed82d82fe635", "258bdec343b9fde1639221a5ae0144a96e552e5288753c5fec76c05fc2fc1870", "4d2ce0062b5eb3a4db95bc1117dd8aa014f6cd50fdc8e64f31f7d41f9231e488", "46d8440685461b00e3ddb891b2ecc6855287d2bd8834a95fb1c1708b00ea5e82", "7c5eb606389556b33d34eb2536459528dc0af97adbcd0ce273aeb650f598d4b2", "4def7a7e5464a140ae9c3a80279fbebce4bd00f9faad819ab7e001512f67a10d", "d9c017dbe355f318d036469eb9b5fbe129fc2b5786a9dc6746a516eab6fe0126" }; const char *SKEIN512_TestOutput[MDTESTCOUNT] = { "bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a", "b1cd8d33f61b3737adfd59bb13ad82f4a9548e92f22956a8976cca3fdb7fee4fe91698146c4197cec85d38b83c5d93bdba92c01fd9a53870d0c7f967bc62bdce", "8f5dd9ec798152668e35129496b029a960c9a9b88662f7f9482f110b31f9f93893ecfb25c009baad9e46737197d5630379816a886aa05526d3a70df272d96e75", "15b73c158ffb875fed4d72801ded0794c720b121c0c78edf45f900937e6933d9e21a3a984206933d504b5dbb2368000411477ee1b204c986068df77886542fcc", "23793ad900ef12f9165c8080da6fdfd2c8354a2929b8aadf83aa82a3c6470342f57cf8c035ec0d97429b626c4d94f28632c8f5134fd367dca5cf293d2ec13f8c", "0c6bed927e022f5ddcf81877d42e5f75798a9f8fd3ede3d83baac0a2f364b082e036c11af35fe478745459dd8f5c0b73efe3c56ba5bb2009208d5a29cc6e469c", "2ca9fcffb3456f297d1b5f407014ecb856f0baac8eb540f534b1f187196f21e88f31103128c2f03fcc9857d7a58eb66f9525e2302d88833ee069295537a434ce", "1131f2aaa0e97126c9314f9f968cc827259bbfabced2943bb8c9274448998fb3b78738b4580dd500c76105fd3c03e465e1414f2c29664286b1f79d3e51128125" }; const char *SKEIN1024_TestOutput[MDTESTCOUNT] = { "0fff9563bb3279289227ac77d319b6fff8d7e9f09da1247b72a0a265cd6d2a62645ad547ed8193db48cff847c06494a03f55666d3b47eb4c20456c9373c86297d630d5578ebd34cb40991578f9f52b18003efa35d3da6553ff35db91b81ab890bec1b189b7f52cb2a783ebb7d823d725b0b4a71f6824e88f68f982eefc6d19c6", "6ab4c4ba9814a3d976ec8bffa7fcc638ceba0544a97b3c98411323ffd2dc936315d13dc93c13c4e88cda6f5bac6f2558b2d8694d3b6143e40d644ae43ca940685cb37f809d3d0550c56cba8036dee729a4f8fb960732e59e64d57f7f7710f8670963cdcdc95b41daab4855fcf8b6762a64b173ee61343a2c7689af1d293eba97", "35a599a0f91abcdb4cb73c19b8cb8d947742d82c309137a7caed29e8e0a2ca7a9ff9a90c34c1908cc7e7fd99bb15032fb86e76df21b72628399b5f7c3cc209d7bb31c99cd4e19465622a049afbb87c03b5ce3888d17e6e667279ec0aa9b3e2712624c01b5f5bbe1a564220bdcf6990af0c2539019f313fdd7406cca3892a1f1f", "ea891f5268acd0fac97467fc1aa89d1ce8681a9992a42540e53babee861483110c2d16f49e73bac27653ff173003e40cfb08516cd34262e6af95a5d8645c9c1abb3e813604d508b8511b30f9a5c1b352aa0791c7d2f27b2706dccea54bc7de6555b5202351751c3299f97c09cf89c40f67187e2521c0fad82b30edbb224f0458", "f23d95c2a25fbcd0e797cd058fec39d3c52d2b5afd7a9af1df934e63257d1d3dcf3246e7329c0f1104c1e51e3d22e300507b0c3b9f985bb1f645ef49835080536becf83788e17fed09c9982ba65c3cb7ffe6a5f745b911c506962adf226e435c42f6f6bc08d288f9c810e807e3216ef444f3db22744441deefa4900982a1371f", "cf3889e8a8d11bfd3938055d7d061437962bc5eac8ae83b1b71c94be201b8cf657fdbfc38674997a008c0c903f56a23feb3ae30e012377f1cfa080a9ca7fe8b96138662653fb3335c7d06595bf8baf65e215307532094cfdfa056bd8052ab792a3944a2adaa47b30335b8badb8fe9eb94fe329cdca04e58bbc530f0af709f469", "cf21a613620e6c119eca31fdfaad449a8e02f95ca256c21d2a105f8e4157048f9fe1e897893ea18b64e0e37cb07d5ac947f27ba544caf7cbc1ad094e675aed77a366270f7eb7f46543bccfa61c526fd628408058ed00ed566ac35a9761d002e629c4fb0d430b2f4ad016fcc49c44d2981c4002da0eecc42144160e2eaea4855a", "e6799b78db54085a2be7ff4c8007f147fa88d326abab30be0560b953396d8802feee9a15419b48a467574e9283be15685ca8a079ee52b27166b64dd70b124b1d4e4f6aca37224c3f2685e67e67baef9f94b905698adc794a09672aba977a61b20966912acdb08c21a2c37001785355dc884751a21f848ab36e590331ff938138" }; static void MDTestSuite(const Algorithm_t *alg) { int i; char buffer[HEX_DIGEST_LENGTH]; printf("%s test suite:\n", alg->name); for (i = 0; i < MDTESTCOUNT; i++) { (*alg->Data)(MDTestInput[i], strlen(MDTestInput[i]), buffer); printf("%s (\"%s\") = %s", alg->name, MDTestInput[i], buffer); if (strcmp(buffer, (*alg->TestOutput)[i]) == 0) { printf(" - verified correct\n"); } else { printf(" - INCORRECT RESULT!\n"); failed = true; } } } static void usage(const Algorithm_t *alg) { switch (mode) { case mode_gnu: fprintf(stderr, "usage: %ssum [-bctwz] [files ...]\n", alg->progname); break; case mode_perl: fprintf(stderr, "usage: shasum [-0bchqstUvw] [-a alg] [files ...]\n"); break; default: fprintf(stderr, "usage: %s [-pqrtx] [-c string] [-s string] [files ...]\n", alg->progname); } exit(1); } static void version(void) { if (mode == mode_gnu) printf("%s (FreeBSD) ", progname); printf("%d.%d\n", __FreeBSD_version / 100000, (__FreeBSD_version / 1000) % 100); exit(0); } diff --git a/sbin/md5/tests/md5_test.sh b/sbin/md5/tests/md5_test.sh index 6b00a6b102c4..5b018b18c220 100644 --- a/sbin/md5/tests/md5_test.sh +++ b/sbin/md5/tests/md5_test.sh @@ -1,384 +1,386 @@ # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2022 Kyle Evans # Copyright (c) 2023 Klara, Inc. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # n=8 algorithms="md5 sha1 sha224 sha256 sha384 sha512 sha512t224 sha512t256 rmd160 skein256 skein512 skein1024" name_bsd_md5="MD5" name_bsd_sha1="SHA1" name_bsd_sha224="SHA224" name_bsd_sha256="SHA256" name_bsd_sha384="SHA384" name_bsd_sha512="SHA512" name_bsd_sha512t224="SHA512t224" name_bsd_sha512t256="SHA512t256" name_bsd_rmd160="RMD160" name_bsd_skein256="Skein256" name_bsd_skein512="Skein512" name_bsd_skein1024="Skein1024" name_perl_sha1="SHA1" name_perl_sha224="SHA224" name_perl_sha256="SHA256" name_perl_sha384="SHA384" name_perl_sha512="SHA512" name_perl_sha512t224="SHA512/224" name_perl_sha512t256="SHA512/256" alg_perl_sha1="" alg_perl_sha224="-a 224" alg_perl_sha256="-a 256" alg_perl_sha384="-a 384" alg_perl_sha512="-a 512" alg_perl_sha512t224="-a 512224" alg_perl_sha512t256="-a 512256" inp_1="" inp_2="a" inp_3="abc" inp_4="message digest" inp_5="abcdefghijklmnopqrstuvwxyz" inp_6="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" inp_7="12345678901234567890123456789012345678901234567890123456789012345678901234567890" inp_8="MD5 has not yet (2001-09-03) been broken, but sufficient attacks have been made that its security is in some doubt" out_1_md5="d41d8cd98f00b204e9800998ecf8427e" out_2_md5="0cc175b9c0f1b6a831c399e269772661" out_3_md5="900150983cd24fb0d6963f7d28e17f72" out_4_md5="f96b697d7cb7938d525a2f31aaf161d0" out_5_md5="c3fcd3d76192e4007dfb496cca67e13b" out_6_md5="d174ab98d277d9f5a5611c2c9f419d9f" out_7_md5="57edf4a22be3c955ac49da2e2107b67a" out_8_md5="b50663f41d44d92171cb9976bc118538" out_1_sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709" out_2_sha1="86f7e437faa5a7fce15d1ddcb9eaeaea377667b8" out_3_sha1="a9993e364706816aba3e25717850c26c9cd0d89d" out_4_sha1="c12252ceda8be8994d5fa0290a47231c1d16aae3" out_5_sha1="32d10c7b8cf96570ca04ce37f2a19d84240d3a89" out_6_sha1="761c457bf73b14d27e9e9265c46f4b4dda11f940" out_7_sha1="50abf5706a150990a08b2c5ea40fa0e585554732" out_8_sha1="18eca4333979c4181199b7b4fab8786d16cf2846" out_1_sha224="d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" out_2_sha224="abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5" out_3_sha224="23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" out_4_sha224="2cb21c83ae2f004de7e81c3c7019cbcb65b71ab656b22d6d0c39b8eb" out_5_sha224="45a5f72c39c5cff2522eb3429799e49e5f44b356ef926bcf390dccc2" out_6_sha224="bff72b4fcb7d75e5632900ac5f90d219e05e97a7bde72e740db393d9" out_7_sha224="b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e" out_8_sha224="5ae55f3779c8a1204210d7ed7689f661fbe140f96f272ab79e19d470" out_1_sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" out_2_sha256="ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" out_3_sha256="ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" out_4_sha256="f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" out_5_sha256="71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" out_6_sha256="db4bfcbd4da0cd85a60c3c37d3fbd8805c77f15fc6b1fdfe614ee0a7c8fdb4c0" out_7_sha256="f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e" out_8_sha256="e6eae09f10ad4122a0e2a4075761d185a272ebd9f5aa489e998ff2f09cbfdd9f" out_1_sha384="38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" out_2_sha384="54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" out_3_sha384="cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" out_4_sha384="473ed35167ec1f5d8e550368a3db39be54639f828868e9454c239fc8b52e3c61dbd0d8b4de1390c256dcbb5d5fd99cd5" out_5_sha384="feb67349df3db6f5924815d6c3dc133f091809213731fe5c7b5f4999e463479ff2877f5f2936fa63bb43784b12f3ebb4" out_6_sha384="1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84" out_7_sha384="b12932b0627d1c060942f5447764155655bd4da0c9afa6dd9b9ef53129af1b8fb0195996d2de9ca0df9d821ffee67026" out_8_sha384="99428d401bf4abcd4ee0695248c9858b7503853acfae21a9cffa7855f46d1395ef38596fcd06d5a8c32d41a839cc5dfb" out_1_sha512="cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" out_2_sha512="1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" out_3_sha512="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" out_4_sha512="107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f3309e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c" out_5_sha512="4dbff86cc2ca1bae1e16468a05cb9881c97f1753bce3619034898faa1aabe429955a1bf8ec483d7421fe3c1646613a59ed5441fb0f321389f77f48a879c7b1f1" out_6_sha512="1e07be23c26a86ea37ea810c8ec7809352515a970e9253c26f536cfc7a9996c45c8370583e0a78fa4a90041d71a4ceab7423f19c71b9d5a3e01249f0bebd5894" out_7_sha512="72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843" out_8_sha512="e8a835195e039708b13d9131e025f4441dbdc521ce625f245a436dcd762f54bf5cb298d96235e6c6a304e087ec8189b9512cbdf6427737ea82793460c367b9c3" out_1_sha512t224="6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4" out_2_sha512t224="d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327" out_3_sha512t224="4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa" out_4_sha512t224="ad1a4db188fe57064f4f24609d2a83cd0afb9b398eb2fcaeaae2c564" out_5_sha512t224="ff83148aa07ec30655c1b40aff86141c0215fe2a54f767d3f38743d8" out_6_sha512t224="a8b4b9174b99ffc67d6f49be9981587b96441051e16e6dd036b140d3" out_7_sha512t224="ae988faaa47e401a45f704d1272d99702458fea2ddc6582827556dd2" out_8_sha512t224="b3c3b945249b0c8c94aba76ea887bcaad5401665a1fbeb384af4d06b" out_1_sha512t256="c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a" out_2_sha512t256="455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8" out_3_sha512t256="53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23" out_4_sha512t256="0cf471fd17ed69d990daf3433c89b16d63dec1bb9cb42a6094604ee5d7b4e9fb" out_5_sha512t256="fc3189443f9c268f626aea08a756abe7b726b05f701cb08222312ccfd6710a26" out_6_sha512t256="cdf1cc0effe26ecc0c13758f7b4a48e000615df241284185c39eb05d355bb9c8" out_7_sha512t256="2c9fdbc0c90bdd87612ee8455474f9044850241dc105b1e8b94b8ddf5fac9148" out_8_sha512t256="dd095fc859b336c30a52548b3dc59fcc0d1be8616ebcf3368fad23107db2d736" out_1_rmd160="9c1185a5c5e9fc54612808977ee8f548b2258d31" out_2_rmd160="0bdc9d2d256b3ee9daae347be6f4dc835a467ffe" out_3_rmd160="8eb208f7e05d987a9b044a8e98c6b087f15a0bfc" out_4_rmd160="5d0689ef49d2fae572b881b123a85ffa21595f36" out_5_rmd160="f71c27109c692c1b56bbdceb5b9d2865b3708dbc" out_6_rmd160="b0e20b6e3116640286ed3a87a5713079b21f5189" out_7_rmd160="9b752e45573d4b39f4dbd3323cab82bf63326bfb" out_8_rmd160="5feb69c6bf7c29d95715ad55f57d8ac5b2b7dd32" out_1_skein256="c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba" out_2_skein256="7fba44ff1a31d71a0c1f82e6e82fb5e9ac6c92a39c9185b9951fed82d82fe635" out_3_skein256="258bdec343b9fde1639221a5ae0144a96e552e5288753c5fec76c05fc2fc1870" out_4_skein256="4d2ce0062b5eb3a4db95bc1117dd8aa014f6cd50fdc8e64f31f7d41f9231e488" out_5_skein256="46d8440685461b00e3ddb891b2ecc6855287d2bd8834a95fb1c1708b00ea5e82" out_6_skein256="7c5eb606389556b33d34eb2536459528dc0af97adbcd0ce273aeb650f598d4b2" out_7_skein256="4def7a7e5464a140ae9c3a80279fbebce4bd00f9faad819ab7e001512f67a10d" out_8_skein256="d9c017dbe355f318d036469eb9b5fbe129fc2b5786a9dc6746a516eab6fe0126" out_1_skein512="bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a" out_2_skein512="b1cd8d33f61b3737adfd59bb13ad82f4a9548e92f22956a8976cca3fdb7fee4fe91698146c4197cec85d38b83c5d93bdba92c01fd9a53870d0c7f967bc62bdce" out_3_skein512="8f5dd9ec798152668e35129496b029a960c9a9b88662f7f9482f110b31f9f93893ecfb25c009baad9e46737197d5630379816a886aa05526d3a70df272d96e75" out_4_skein512="15b73c158ffb875fed4d72801ded0794c720b121c0c78edf45f900937e6933d9e21a3a984206933d504b5dbb2368000411477ee1b204c986068df77886542fcc" out_5_skein512="23793ad900ef12f9165c8080da6fdfd2c8354a2929b8aadf83aa82a3c6470342f57cf8c035ec0d97429b626c4d94f28632c8f5134fd367dca5cf293d2ec13f8c" out_6_skein512="0c6bed927e022f5ddcf81877d42e5f75798a9f8fd3ede3d83baac0a2f364b082e036c11af35fe478745459dd8f5c0b73efe3c56ba5bb2009208d5a29cc6e469c" out_7_skein512="2ca9fcffb3456f297d1b5f407014ecb856f0baac8eb540f534b1f187196f21e88f31103128c2f03fcc9857d7a58eb66f9525e2302d88833ee069295537a434ce" out_8_skein512="1131f2aaa0e97126c9314f9f968cc827259bbfabced2943bb8c9274448998fb3b78738b4580dd500c76105fd3c03e465e1414f2c29664286b1f79d3e51128125" out_1_skein1024="0fff9563bb3279289227ac77d319b6fff8d7e9f09da1247b72a0a265cd6d2a62645ad547ed8193db48cff847c06494a03f55666d3b47eb4c20456c9373c86297d630d5578ebd34cb40991578f9f52b18003efa35d3da6553ff35db91b81ab890bec1b189b7f52cb2a783ebb7d823d725b0b4a71f6824e88f68f982eefc6d19c6" out_2_skein1024="6ab4c4ba9814a3d976ec8bffa7fcc638ceba0544a97b3c98411323ffd2dc936315d13dc93c13c4e88cda6f5bac6f2558b2d8694d3b6143e40d644ae43ca940685cb37f809d3d0550c56cba8036dee729a4f8fb960732e59e64d57f7f7710f8670963cdcdc95b41daab4855fcf8b6762a64b173ee61343a2c7689af1d293eba97" out_3_skein1024="35a599a0f91abcdb4cb73c19b8cb8d947742d82c309137a7caed29e8e0a2ca7a9ff9a90c34c1908cc7e7fd99bb15032fb86e76df21b72628399b5f7c3cc209d7bb31c99cd4e19465622a049afbb87c03b5ce3888d17e6e667279ec0aa9b3e2712624c01b5f5bbe1a564220bdcf6990af0c2539019f313fdd7406cca3892a1f1f" out_4_skein1024="ea891f5268acd0fac97467fc1aa89d1ce8681a9992a42540e53babee861483110c2d16f49e73bac27653ff173003e40cfb08516cd34262e6af95a5d8645c9c1abb3e813604d508b8511b30f9a5c1b352aa0791c7d2f27b2706dccea54bc7de6555b5202351751c3299f97c09cf89c40f67187e2521c0fad82b30edbb224f0458" out_5_skein1024="f23d95c2a25fbcd0e797cd058fec39d3c52d2b5afd7a9af1df934e63257d1d3dcf3246e7329c0f1104c1e51e3d22e300507b0c3b9f985bb1f645ef49835080536becf83788e17fed09c9982ba65c3cb7ffe6a5f745b911c506962adf226e435c42f6f6bc08d288f9c810e807e3216ef444f3db22744441deefa4900982a1371f" out_6_skein1024="cf3889e8a8d11bfd3938055d7d061437962bc5eac8ae83b1b71c94be201b8cf657fdbfc38674997a008c0c903f56a23feb3ae30e012377f1cfa080a9ca7fe8b96138662653fb3335c7d06595bf8baf65e215307532094cfdfa056bd8052ab792a3944a2adaa47b30335b8badb8fe9eb94fe329cdca04e58bbc530f0af709f469" out_7_skein1024="cf21a613620e6c119eca31fdfaad449a8e02f95ca256c21d2a105f8e4157048f9fe1e897893ea18b64e0e37cb07d5ac947f27ba544caf7cbc1ad094e675aed77a366270f7eb7f46543bccfa61c526fd628408058ed00ed566ac35a9761d002e629c4fb0d430b2f4ad016fcc49c44d2981c4002da0eecc42144160e2eaea4855a" out_8_skein1024="e6799b78db54085a2be7ff4c8007f147fa88d326abab30be0560b953396d8802feee9a15419b48a467574e9283be15685ca8a079ee52b27166b64dd70b124b1d4e4f6aca37224c3f2685e67e67baef9f94b905698adc794a09672aba977a61b20966912acdb08c21a2c37001785355dc884751a21f848ab36e590331ff938138" for alg in $algorithms ; do eval " atf_test_case self_test_${alg} self_test_${alg}_head() { atf_set descr \"self-test for \$name_bsd_${alg}\" atf_set require.progs \"${alg}\" } self_test_${alg}_body() { atf_check -o ignore ${alg} --self-test } " for i in $(seq $n) ; do eval " atf_test_case bsd_${alg}_vec${i} bsd_${alg}_vec${i}_head() { atf_set descr \"BSD mode \$name_bsd_${alg} test vector ${i}\" atf_set require.progs \"${alg}\" } bsd_${alg}_vec${i}_body() { printf '%s' \"\$inp_${i}\" >in atf_check -o inline:\"\$out_${i}_${alg}\n\" ${alg} in atf_check -o inline:\"\$out_${i}_${alg} -\n\" ${alg}sum in atf_check -o inline:\"\$out_${i}_${alg} -\n\" shasum \$alg_perl_${alg} digests :>stdout :>stderr rv=0 printf '%s' \"\$inp_2\" >inp2 printf '%s inp%d\n' \"\$out_2_${alg}\" 2 >>digests printf 'inp%d: OK\n' 2 >>stdout atf_check -o file:stdout -e file:stderr -s exit:$rv ${alg}sum -c digests printf '%s' \"\$inp_3\" >inp3 printf '%s inp%d\n' \"malformed\" 3 >>digests printf '%ssum: WARNING: 1 line is improperly formatted\n' ${alg} >>stderr rv=1 atf_check -o file:stdout -e file:stderr -s exit:$rv ${alg}sum -c digests printf '%s' \"\$inp_4\" >inp4 printf '%s inp%d\n' \"\$out_4_${alg}\" 4 | tr abcdef fedcba >>digests printf 'inp%d: FAILED\n' 4 >>stdout printf '%ssum: WARNING: 1 computed checksum did NOT match\n' ${alg} >>stderr atf_check -o file:stdout -e file:stderr -s exit:$rv ${alg}sum -c digests grep -v OK stdout >quiet atf_check -o file:quiet -e file:stderr -s exit:$rv ${alg}sum --check --quiet digests atf_check -s exit:$rv ${alg}sum --check --status digests } " eval " atf_test_case perl_check_${alg} perl_check_${alg}_head() { atf_set descr \"Perl mode check test for \$name_bsd_${alg}\" atf_set require.progs \"shasum\" } perl_check_${alg}_body() { [ -n \"\$name_perl_${alg}\" ] || atf_skip \"shasum does not support ${alg}\" :>digests :>stdout :>stderr rv=0 printf '%s' \"\$inp_2\" >inp2 printf '%s inp%d\n' \"\$out_2_${alg}\" 2 >>digests printf 'inp%d: OK\n' 2 >>stdout atf_check -o file:stdout -e file:stderr -s exit:$rv shasum \$alg_perl_${alg} -c digests printf '%s' \"\$inp_3\" >inp3 printf '%s inp%d\n' \"malformed\" 3 >>digests printf 'shasum: WARNING: 1 line is improperly formatted\n' >>stderr rv=1 atf_check -o file:stdout -e file:stderr -s exit:$rv shasum \$alg_perl_${alg} -c digests printf '%s' \"\$inp_4\" >inp4 printf '%s inp%d\n' \"\$out_4_${alg}\" 4 | tr abcdef fedcba >>digests printf 'inp%d: FAILED\n' 4 >>stdout printf 'shasum: WARNING: 1 computed checksum did NOT match\n' >>stderr atf_check -o file:stdout -e file:stderr -s exit:$rv shasum \$alg_perl_${alg} -c digests grep -v OK stdout >quiet atf_check -o file:quiet -e file:stderr -s exit:$rv shasum \$alg_perl_${alg} --check --quiet digests atf_check -s exit:$rv shasum \$alg_perl_${alg} --check --status digests } " done atf_test_case gnu_bflag gnu_bflag_head() { atf_set descr "Verify GNU binary mode" atf_set require.progs "sha256sum" } gnu_bflag_body() { echo foo >a echo bar >b (sha256 -q a | tr -d '\n'; echo " *a") > expected (sha256 -q b | tr -d '\n'; echo " *b") >> expected atf_check -o file:expected sha256sum -b a b atf_check -o file:expected sha256sum --binary a b } atf_test_case gnu_cflag gnu_cflag_head() { atf_set descr "Verify handling of missing files in GNU check mode" atf_set require.progs "sha256sum" } gnu_cflag_body() { # Verify that the *sum -c mode works even if some files are missing. # PR 267722 identified that we would never advance past the first record # to check against. As a result, things like checking the published # checksums for the install media became a more manual process again if # you didn't download all of the images. for i in 2 3 4 ; do eval "printf '%s inp%d\n' \"\$out_${i}_sha256\" ${i}" done >digests for combo in "2 3 4" "3 4" "2 4" "2 3" "2" "3" "4" ""; do rm -f inp2 inp3 inp4 :> expected cnt=0 for i in ${combo}; do eval "printf '%s' \"\$inp_${i}\"" > inp${i} printf "inp%d: OK\n" ${i} >> expected cnt=$((cnt + 1)) done err=0 [ "$cnt" -eq 3 ] || err=1 atf_check -o file:expected -e ignore -s exit:${err} \ sha256sum -c digests atf_check -o file:expected -e ignore -s exit:0 \ sha256sum --ignore-missing -c digests done } atf_init_test_cases() { for alg in $algorithms ; do atf_add_test_case self_test_${alg} for i in $(seq $n) ; do atf_add_test_case bsd_${alg}_vec${i} atf_add_test_case gnu_${alg}_vec${i} atf_add_test_case perl_${alg}_vec${i} done atf_add_test_case gnu_check_${alg} atf_add_test_case perl_check_${alg} done atf_add_test_case gnu_bflag atf_add_test_case gnu_cflag }