summaryrefslogtreecommitdiffhomepage
path: root/libtomcrypt/demos/hashsum.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtomcrypt/demos/hashsum.c')
-rw-r--r--libtomcrypt/demos/hashsum.c333
1 files changed, 257 insertions, 76 deletions
diff --git a/libtomcrypt/demos/hashsum.c b/libtomcrypt/demos/hashsum.c
index 4e31501..aee0bd2 100644
--- a/libtomcrypt/demos/hashsum.c
+++ b/libtomcrypt/demos/hashsum.c
@@ -1,3 +1,12 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
/*
* Written by Daniel Richards <kyhwana@world-net.co.nz> 6/7/2002
* hash.c: This app uses libtomcrypt to hash either stdin or a file
@@ -9,111 +18,283 @@
#include <tomcrypt.h>
-int errno;
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
+#include <libgen.h>
+#else
+#define basename(x) x
+#endif
-void register_algs();
+#if !defined(PATH_MAX) && defined(_MSC_VER)
+#include <windows.h>
+#define PATH_MAX MAX_PATH
+#endif
-int main(int argc, char **argv)
+/* thanks http://stackoverflow.com/a/8198009 */
+#define _base(x) ((x >= '0' && x <= '9') ? '0' : \
+ (x >= 'a' && x <= 'f') ? 'a' - 10 : \
+ (x >= 'A' && x <= 'F') ? 'A' - 10 : \
+ '\255')
+#define HEXOF(x) (x - _base(x))
+
+static char* hashsum;
+
+static void cleanup(void)
{
- int idx, x, z;
- unsigned long w;
- unsigned char hash_buffer[MAXBLOCKSIZE];
- hash_state md;
+ free(hashsum);
+}
- /* You need to register algorithms before using them */
- register_algs();
- if (argc < 2) {
- printf("usage: ./hash algorithm file [file ...]\n");
- printf("Algorithms:\n");
- for (x = 0; hash_descriptor[x].name != NULL; x++) {
- printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID);
+static void die(int status)
+{
+ unsigned long w, x;
+ FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
+ fprintf(o, "usage: %s -a algorithm [-c] [file...]\n\n", hashsum);
+ fprintf(o, "\t-c\tCheck the hash(es) of the file(s) written in [file].\n");
+ fprintf(o, "\t\t(-a not required)\n");
+ fprintf(o, "\nAlgorithms:\n\t");
+ w = 0;
+ for (x = 0; hash_descriptor[x].name != NULL; x++) {
+ w += fprintf(o, "%-14s", hash_descriptor[x].name);
+ if (w >= 70) {
+ fprintf(o, "\n\t");
+ w = 0;
}
- exit(EXIT_SUCCESS);
}
+ if (w != 0) fprintf(o, "\n");
+ exit(status);
+}
- idx = find_hash(argv[1]);
- if (idx == -1) {
- fprintf(stderr, "\nInvalid hash specified on command line.\n");
- return -1;
+static void printf_hex(unsigned char* hash_buffer, unsigned long w)
+{
+ unsigned long x;
+ for (x = 0; x < w; x++) {
+ printf("%02x",hash_buffer[x]);
}
+}
- if (argc == 2) {
- hash_descriptor[idx].init(&md);
- do {
- x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin);
- hash_descriptor[idx].process(&md, hash_buffer, x);
- } while (x == sizeof(hash_buffer));
- hash_descriptor[idx].done(&md, hash_buffer);
- for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
- printf("%02x",hash_buffer[x]);
+static void check_file(int argn, int argc, char **argv)
+{
+ int err, failed, invalid;
+ unsigned char is_buffer[MAXBLOCKSIZE], should_buffer[MAXBLOCKSIZE];
+ char buf[PATH_MAX + (MAXBLOCKSIZE * 3)];
+ /* iterate through all files */
+ while(argn < argc) {
+ char* s;
+ FILE* f = fopen(argv[argn], "rb");
+ if(f == NULL) {
+ int n = snprintf(buf, sizeof(buf), "%s: %s", hashsum, argv[argn]);
+ if (n > 0 && n < (int)sizeof(buf))
+ perror(buf);
+ else
+ perror(argv[argn]);
+ exit(EXIT_FAILURE);
}
- printf(" (stdin)\n");
- } else {
- for (z = 2; z < argc; z++) {
- w = sizeof(hash_buffer);
- if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) {
- printf("File hash error: %s\n", error_to_string(errno));
- } else {
- for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
- printf("%02x",hash_buffer[x]);
- }
- printf(" %s\n", argv[z]);
+ failed = 0;
+ invalid = 0;
+ /* read the file line by line */
+ while((s = fgets(buf, sizeof(buf), f)) != NULL)
+ {
+ int tries, n;
+ unsigned long hash_len, w, x;
+ char* space = strstr(s, " ");
+
+ /* skip lines with comments */
+ if (buf[0] == '#') continue;
+
+ if (space == NULL) {
+ fprintf(stderr, "%s: no properly formatted checksum lines found\n", hashsum);
+ goto ERR;
+ }
+
+ hash_len = space - s;
+ hash_len /= 2;
+
+ if (hash_len > sizeof(should_buffer)) {
+ fprintf(stderr, "%s: hash too long\n", hashsum);
+ goto ERR;
+ }
+
+ /* convert the hex-string back to binary */
+ for (x = 0; x < hash_len; ++x) {
+ should_buffer[x] = HEXOF(s[x*2]) << 4 | HEXOF(s[x*2 + 1]);
}
+
+ space++;
+ if (*space != '*') {
+ fprintf(stderr, "%s: unsupported input mode '%c'\n", hashsum, *space);
+ goto ERR;
+ }
+ space++;
+
+ for (n = 0; n < (buf + sizeof(buf)) - space; ++n) {
+ if(iscntrl((int)space[n])) {
+ space[n] = '\0';
+ break;
+ }
+ }
+
+ /* try all hash algorithms that have the appropriate hash size */
+ tries = 0;
+ for (x = 0; hash_descriptor[x].name != NULL; ++x) {
+ if (hash_descriptor[x].hashsize == hash_len) {
+ tries++;
+ w = sizeof(is_buffer);
+ if ((err = hash_file(x, space, is_buffer, &w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s: %s\n", hashsum, space, error_to_string(err));
+ERR:
+ fclose(f);
+ exit(EXIT_FAILURE);
+ }
+ if(XMEMCMP(should_buffer, is_buffer, w) == 0) {
+ printf("%s: OK\n", space);
+ break;
+ }
+ }
+ } /* for */
+ if (hash_descriptor[x].name == NULL) {
+ if(tries > 0) {
+ printf("%s: FAILED\n", space);
+ failed++;
+ }
+ else {
+ invalid++;
+ }
+ }
+ } /* while */
+ fclose(f);
+ if(invalid) {
+ fprintf(stderr, "%s: WARNING: %d %s is improperly formatted\n", hashsum, invalid, invalid > 1?"lines":"line");
+ }
+ if(failed) {
+ fprintf(stderr, "%s: WARNING: %d computed %s did NOT match\n", hashsum, failed, failed > 1?"checksums":"checksum");
}
+ argn++;
}
- return EXIT_SUCCESS;
+ exit(EXIT_SUCCESS);
}
-void register_algs(void)
+int main(int argc, char **argv)
{
- int err;
+ int idxs[TAB_SIZE], idx, check, y, z, err, argn;
+ unsigned long w, x;
+ unsigned char hash_buffer[MAXBLOCKSIZE];
-#ifdef LTC_TIGER
- register_hash (&tiger_desc);
-#endif
-#ifdef LTC_MD2
- register_hash (&md2_desc);
-#endif
-#ifdef LTC_MD4
- register_hash (&md4_desc);
-#endif
-#ifdef LTC_MD5
- register_hash (&md5_desc);
-#endif
+ hashsum = strdup(basename(argv[0]));
+ atexit(cleanup);
+
+ /* You need to register algorithms before using them */
+ register_all_ciphers();
+ register_all_hashes();
+ if (argc > 1 && (strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0)) {
+ die(EXIT_SUCCESS);
+ }
+ if (argc < 3) {
+ die(EXIT_FAILURE);
+ }
+
+ for (x = 0; x < sizeof(idxs)/sizeof(idxs[0]); ++x) {
+ idxs[x] = -2;
+ }
+ argn = 1;
+ check = 0;
+ idx = 0;
+
+ while(argn < argc){
+ if(strcmp("-a", argv[argn]) == 0) {
+ argn++;
+ if(argn < argc) {
+ idxs[idx] = find_hash(argv[argn]);
+ if (idxs[idx] == -1) {
+ struct {
+ const char* is;
+ const char* should;
+ } shasum_compat[] =
+ {
#ifdef LTC_SHA1
- register_hash (&sha1_desc);
+ { "1", sha1_desc.name },
#endif
#ifdef LTC_SHA224
- register_hash (&sha224_desc);
+ { "224", sha224_desc.name },
#endif
#ifdef LTC_SHA256
- register_hash (&sha256_desc);
+ { "256", sha256_desc.name },
#endif
#ifdef LTC_SHA384
- register_hash (&sha384_desc);
+ { "384", sha384_desc.name },
#endif
#ifdef LTC_SHA512
- register_hash (&sha512_desc);
-#endif
-#ifdef LTC_RIPEMD128
- register_hash (&rmd128_desc);
+ { "512", sha512_desc.name },
#endif
-#ifdef LTC_RIPEMD160
- register_hash (&rmd160_desc);
+#ifdef LTC_SHA512_224
+ { "512224", sha512_224_desc.name },
#endif
-#ifdef LTC_WHIRLPOOL
- register_hash (&whirlpool_desc);
-#endif
-#ifdef LTC_CHC_HASH
- register_hash(&chc_desc);
- if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) {
- printf("chc_register error: %s\n", error_to_string(err));
- exit(EXIT_FAILURE);
- }
+#ifdef LTC_SHA512_256
+ { "512256", sha512_256_desc.name },
#endif
+ { NULL, NULL }
+ };
+ for (x = 0; shasum_compat[x].is != NULL; ++x) {
+ if(XSTRCMP(shasum_compat[x].is, argv[argn]) == 0) {
+ idxs[idx] = find_hash(shasum_compat[x].should);
+ break;
+ }
+ }
+ }
+ if (idxs[idx] == -1) {
+ fprintf(stderr, "%s: Unrecognized algorithm\n", hashsum);
+ die(EXIT_FAILURE);
+ }
+ idx++;
+ if ((size_t)idx >= sizeof(idxs)/sizeof(idxs[0])) {
+ fprintf(stderr, "%s: Too many '-a' options chosen\n", hashsum);
+ die(EXIT_FAILURE);
+ }
+ argn++;
+ continue;
+ }
+ else {
+ die(EXIT_FAILURE);
+ }
+ }
+ if(strcmp("-c", argv[argn]) == 0) {
+ check = 1;
+ argn++;
+ continue;
+ }
+ break;
+ }
+
+ if (check == 1) {
+ check_file(argn, argc, argv);
+ }
+ if (argc == argn) {
+ w = sizeof(hash_buffer);
+ if ((err = hash_filehandle(idxs[0], stdin, hash_buffer, &w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
+ return EXIT_FAILURE;
+ } else {
+ for (x = 0; x < w; x++) {
+ printf("%02x",hash_buffer[x]);
+ }
+ printf(" *-\n");
+ }
+ } else {
+ for (z = argn; z < argc; z++) {
+ for (y = 0; y < idx; ++y) {
+ w = sizeof(hash_buffer);
+ if ((err = hash_file(idxs[y],argv[z],hash_buffer,&w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
+ return EXIT_FAILURE;
+ } else {
+ printf_hex(hash_buffer, w);
+ printf(" *%s\n", argv[z]);
+ }
+ }
+ }
+ }
+ return EXIT_SUCCESS;
}
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */