head 1.1; branch 1.1.1; access ; symbols multigest-base:1.1.1.1 CROOKS:1.1.1; locks ; strict; comment @# @; 1.1 date 2013.08.16.06.47.53; author agc; state Exp; branches 1.1.1.1; next ; commitid mbzkWnMLSTok6E1x; 1.1.1.1 date 2013.08.16.06.47.53; author agc; state Exp; branches ; next ; commitid mbzkWnMLSTok6E1x; desc @@ 1.1 log @Initial revision @ text @/* $NetBSD$ */ /* * Copyright (c) 2001-2005 Alistair G. Crooks. All rights reserved. * * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Alistair G. Crooks. * 4. The name of the author may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef lint __COPYRIGHT("@@(#) Copyright (c) 2001-2005 \ The NetBSD Foundation, Inc. All rights reserved."); __RCSID("$NetBSD$"); #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_LOCALE_H #include #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif typedef void (*HASH_init)(void *); typedef void (*HASH_update)(void *, const uint8_t *, size_t); typedef char *(*HASH_end)(void *, char *); typedef char *(*HASH_file)(char *, char *); /* this struct defines a message digest algorithm */ typedef struct alg_t { const char *name; int hash_len; HASH_init hash_init; HASH_update hash_update; HASH_end hash_end; HASH_file hash_file; union { MD5_CTX m; SHA1_CTX sha; RMD160_CTX rmd; SHA256_CTX sha256; SHA384_CTX sha384; SHA512_CTX sha512; tiger_context_t tiger; whirlpool_context_t whirlpool; } hash_ctx, hash_ctx2; } alg_t; /* list of supported message digest algorithms */ static alg_t algorithms[] = { { "MD5", 16, (HASH_init) MD5Init, (HASH_update) MD5Update, (HASH_end) MD5End, (HASH_file) MD5File }, { "RMD160", 20, (HASH_init) RMD160Init, (HASH_update) RMD160Update, (HASH_end) RMD160End, (HASH_file) RMD160File }, { "SHA1", 20, (HASH_init) SHA1Init, (HASH_update) SHA1Update, (HASH_end) SHA1End, (HASH_file) SHA1File }, { "SHA256", SHA256_DIGEST_LENGTH, (HASH_init) SHA256_Init, (HASH_update) SHA256_Update, (HASH_end) SHA256_End, (HASH_file) SHA256_File }, { "SHA384", SHA384_DIGEST_LENGTH, (HASH_init) SHA384_Init, (HASH_update) SHA384_Update, (HASH_end) SHA384_End, (HASH_file) SHA384_File }, { "SHA512", SHA512_DIGEST_LENGTH, (HASH_init) SHA512_Init, (HASH_update) SHA512_Update, (HASH_end) SHA512_End, (HASH_file) SHA512_File }, { "TIGER", 24, (HASH_init) TIGERInit, (HASH_update) TIGERUpdate, (HASH_end) TIGEREnd, (HASH_file) TIGERFile }, { "WHIRLPOOL", WHIRLPOOL_DIGEST_BYTES, (HASH_init) whirlpool_init, (HASH_update) whirlpool_update, (HASH_end) whirlpool_end, (HASH_file) whirlpool_file }, { NULL } }; /* find an algorithm, given a name */ static alg_t * find_algorithm(const char *a) { alg_t *alg; for (alg = algorithms ; alg->name && strcasecmp(alg->name, a) != 0 ; alg++) { } return (alg->name) ? alg : NULL; } /* compute a digest, and print the results if successful */ static int digest_file(char *fn, alg_t *alg) { char in[BUFSIZ * 20]; char *digest; int cc, rc; digest = malloc(alg->hash_len * 2 + 1); if (fn == NULL) { (*alg->hash_init)(&alg->hash_ctx); while ((cc = read(STDIN_FILENO, in, sizeof(in))) > 0) { (*alg->hash_update)(&alg->hash_ctx, (uint8_t *)in, (unsigned) cc); } (void) printf("%s\n", (*alg->hash_end)(&alg->hash_ctx, digest)); rc = 1; } else { if ((*alg->hash_file)(fn, digest) == NULL) { rc = 0; } else { (void) printf("%s (%s) = %s\n", alg->name, fn, digest); rc = 1; } } free(digest); return (rc); } int main(int argc, char **argv) { alg_t *alg; int rval; int i; #ifdef HAVE_SETLOCALE (void) setlocale(LC_ALL, ""); #endif while ((i = getopt(argc, argv, "V")) != -1) { switch(i) { case 'V': printf("%s\n", VERSION); return EXIT_SUCCESS; } } argc -= optind; argv += optind; if (argc == 0) { (void) fprintf(stderr, "Usage: %s algorithm [file...]\n", argv[-optind]); return EXIT_FAILURE; } if ((alg = find_algorithm(argv[0])) == NULL) { (void) fprintf(stderr, "No such algorithm `%s'\n", argv[0]); exit(EXIT_FAILURE); } argc--; argv++; rval = EXIT_SUCCESS; if (argc == 0) { if (!digest_file(NULL, alg)) { (void) fprintf(stderr, "stdin\n"); rval = EXIT_FAILURE; } } else { for (i = 0 ; i < argc ; i++) { if (!digest_file(argv[i], alg)) { (void) fprintf(stderr, "%s\n", argv[i]); rval = EXIT_FAILURE; } } } return rval; } @ 1.1.1.1 log @multigest is a library and utility program which calculates multiple digests in parallel. The resulting digests are concatenated to make one large digest value. The following digest types are supported: BLAKE2 CRC32C MD5 RMD160 SHA1 SHA256 SHA3-224 SHA3-256 SHA3-384 SHA3-512 SHA512 SIZE TIGER2 TIGER WHIRLPOOL 2 separate interfaces are provided to the multigest routines, and these mirror the existing digest interfaces: 1. Low-level interface *_init(), *_update() and *_final() functions 2. High-level interface *_data and *_file functions Version Control System Identifiers ($Id$, $NetBSD$, etc) can be normalised using the -s /regexp/replacement/ argument. The -r argument is a shorthand for normalising the RCS/CVS identifiers, $Id$ and $NetBSD$ Multiple digests are specified as part of a comma-specified list. multigest includes new digest functions, such as the keccak/sha3 family of digests, as well as blake2 (also from the sha3 contest). crc32c is provided as a lightweight digest. A size pseudo-digest algorithm is provided (suggested a long time ago by tron). There is also a "check" command line argument, which allows files to be compared to previously calculated multigest output. Sample usage as follows: % multigest -a sha1,sha256 2.in SHA1,SHA256 (bin/2.in) () = 564d6d5d84ba22fb47dded32b90578ef31124457eead5829df188e5e0f06be2760fea7814bb0844121f6dc61da1d0e65896fe445 % multigest -r -a sha1,sha256 2.in SHA1,SHA256 (bin/2.in) (,\$(Id|NetBSD)[^\n]*\$,$NetBSD$) = 114f266e7a71dc51811df9dc994bce4de69170c9835bc89fbf57f3a6aa9168b776bd3ef2ba6bcf6e6934a12380b10272ae73679c % echo -n "The quick brown fox jumps over the lazy dog" | multigest -a sha3-512 d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609 which matches the output shown on the wikipedia page for keccak: http://en.wikipedia.org/wiki/SHA-3 To check previously calculated multigest values: % multigest -o calculated -a crc32c,md5,rmd160,sha1,sha256,sha512 -r 2.in % cat calculated CRC32C,MD5,RMD160,SHA1,SHA256,SHA512 (2.in) (,\$(Id|NetBSD)[^\n]*\$,$NetBSD$) = 279934d7b43c46ba05e28788df71eaea4777912ffaad8f20db6708582703a0ef4bc79a61c34a91bc114f266e7a71dc51811df9dc994bce4de69170c9835bc89fbf57f3a6aa9168b776bd3ef2ba6bcf6e6934a12380b10272ae73679ca92644bdf34583700776b58728501c15ee8300feb6ddba910c462618bce2221a0445036a2d46e676ef32988283372710701eb39fa7a59821b740bf07a3d364a5 % multigest -c calculated provided digest: '279934d7b43c46ba05e28788df71eaea4777912ffaad8f20db6708582703a0ef4bc79a61c34a91bc114f266e7a71dc51811df9dc994bce4de69170c9835bc89fbf57f3a6aa9168b776bd3ef2ba6bcf6e6934a12380b10272ae73679ca92644bdf34583700776b58728501c15ee8300feb6ddba910c462618bce2221a0445036a2d46e676ef32988283372710701eb39fa7a59821b740bf07a3d364a5' calculated digest: '279934d7b43c46ba05e28788df71eaea4777912ffaad8f20db6708582703a0ef4bc79a61c34a91bc114f266e7a71dc51811df9dc994bce4de69170c9835bc89fbf57f3a6aa9168b776bd3ef2ba6bcf6e6934a12380b10272ae73679ca92644bdf34583700776b58728501c15ee8300feb6ddba910c462618bce2221a0445036a2d46e676ef32988283372710701eb39fa7a59821b740bf07a3d364a5' % @ text @@