| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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 | 
					
						
							|  |  |  |  * This file is Public Domain. No rights are reserved. | 
					
						
							|  |  |  |  * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt' | 
					
						
							|  |  |  |  * This example isn't really big enough to warrent splitting into | 
					
						
							|  |  |  |  * more functions ;) | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-30 23:55:53 +00:00
										 |  |  | #include <tomcrypt.h>
 | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 14:10:24 +02:00
										 |  |  | #if _POSIX_C_SOURCE >= 200112L
 | 
					
						
							|  |  |  | #include <libgen.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define basename(x) x
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 13:52:39 +02:00
										 |  |  | #include "common.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 18:31:14 +02:00
										 |  |  | #if !defined(PATH_MAX) && defined(_MSC_VER)
 | 
					
						
							|  |  |  | #include <windows.h>
 | 
					
						
							|  |  |  | #define PATH_MAX MAX_PATH
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  | /* 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))
 | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  | static char* hashsum; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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", hashsum); | 
					
						
							|  |  |  |    fprintf(o, "Algorithms:\n"); | 
					
						
							|  |  |  |    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"); | 
					
						
							|  |  |  |          w = 0; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    if (w != 0) fprintf(o, "\n"); | 
					
						
							|  |  |  |    free(hashsum); | 
					
						
							|  |  |  |    exit(status); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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]); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       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, " "); | 
					
						
							|  |  |  |          if (space == NULL) { | 
					
						
							|  |  |  |             fprintf(stderr, "%s: no properly formatted checksum lines found\n", hashsum); | 
					
						
							|  |  |  |             goto ERR; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          hash_len = space - s; | 
					
						
							|  |  |  |          hash_len /= 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          /* 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) { | 
					
						
							| 
									
										
										
										
											2017-05-11 20:37:06 +02:00
										 |  |  |             if(iscntrl((int)space[n])) { | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |                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) { | 
					
						
							| 
									
										
										
										
											2017-05-02 01:13:35 +02:00
										 |  |  |                   fprintf(stderr, "%s: File hash error: %s: %s\n", hashsum, space, error_to_string(err)); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  | 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++; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    exit(EXIT_SUCCESS); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char **argv) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |    int idx, check, z, err, argn; | 
					
						
							| 
									
										
										
										
											2017-04-23 22:37:32 +02:00
										 |  |  |    unsigned long w, x; | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |    unsigned char hash_buffer[MAXBLOCKSIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |    hashsum = strdup(basename(argv[0])); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |    /* You need to register algorithms before using them */ | 
					
						
							|  |  |  |    register_algs(); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |    if (argc > 1 && (strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0)) { | 
					
						
							|  |  |  |       die(EXIT_SUCCESS); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    if (argc < 3) { | 
					
						
							|  |  |  |       die(EXIT_FAILURE); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    argn = 1; | 
					
						
							|  |  |  |    check = 0; | 
					
						
							|  |  |  |    idx = -2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    while(argn < argc){ | 
					
						
							|  |  |  |       if(strcmp("-a", argv[argn]) == 0) { | 
					
						
							|  |  |  |          argn++; | 
					
						
							|  |  |  |          if(argn < argc) { | 
					
						
							|  |  |  |             idx = find_hash(argv[argn]); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |             if (idx == -1) { | 
					
						
							|  |  |  |                struct { | 
					
						
							|  |  |  |                   const char* is; | 
					
						
							|  |  |  |                   const char* should; | 
					
						
							|  |  |  |                } shasum_compat[] = | 
					
						
							|  |  |  |                      { | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #ifdef LTC_SHA1
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "1",        sha1_desc.name }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA224
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "224",      sha224_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA256
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "256",      sha256_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA384
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "384",      sha384_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA512
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "512",      sha512_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA512_224
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "512224",   sha512_224_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef LTC_SHA512_256
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                            { "512256",   sha512_256_desc.name  }, | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |                            { NULL, NULL } | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                      }; | 
					
						
							| 
									
										
										
										
											2017-05-02 01:09:01 +02:00
										 |  |  |                for (x = 0; shasum_compat[x].is != NULL; ++x) { | 
					
						
							| 
									
										
										
										
											2017-05-01 21:58:21 +02:00
										 |  |  |                   if(XSTRCMP(shasum_compat[x].is, argv[argn]) == 0) { | 
					
						
							|  |  |  |                      idx = find_hash(shasum_compat[x].should); | 
					
						
							|  |  |  |                      break; | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |             if (idx == -1) { | 
					
						
							| 
									
										
										
										
											2017-05-02 01:13:35 +02:00
										 |  |  |                fprintf(stderr, "%s: Unrecognized algorithm\n", hashsum); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |                die(EXIT_FAILURE); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             argn++; | 
					
						
							|  |  |  |             continue; | 
					
						
							| 
									
										
										
										
											2017-05-01 14:10:24 +02:00
										 |  |  |          } | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |          else { | 
					
						
							|  |  |  |             die(EXIT_FAILURE); | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if(strcmp("-c", argv[argn]) == 0) { | 
					
						
							|  |  |  |          check = 1; | 
					
						
							|  |  |  |          argn++; | 
					
						
							|  |  |  |          continue; | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |    if (check == 1) { | 
					
						
							|  |  |  |       check_file(argn, argc, argv); | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |    if (argc == argn) { | 
					
						
							| 
									
										
										
										
											2017-04-23 22:37:32 +02:00
										 |  |  |       w = sizeof(hash_buffer); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |       if ((err = hash_filehandle(idx, stdin, hash_buffer, &w)) != CRYPT_OK) { | 
					
						
							| 
									
										
										
										
											2017-05-02 01:13:35 +02:00
										 |  |  |          fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err)); | 
					
						
							| 
									
										
										
										
											2017-05-01 14:10:24 +02:00
										 |  |  |          return EXIT_FAILURE; | 
					
						
							| 
									
										
										
										
											2017-04-23 22:37:32 +02:00
										 |  |  |       } else { | 
					
						
							|  |  |  |           for (x = 0; x < w; x++) { | 
					
						
							|  |  |  |               printf("%02x",hash_buffer[x]); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           printf(" *-\n"); | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |    } else { | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |       for (z = 3; z < argc; z++) { | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |          w = sizeof(hash_buffer); | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |          if ((err = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { | 
					
						
							| 
									
										
										
										
											2017-05-02 01:13:35 +02:00
										 |  |  |             fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err)); | 
					
						
							| 
									
										
										
										
											2017-05-01 14:10:24 +02:00
										 |  |  |             return EXIT_FAILURE; | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |          } else { | 
					
						
							| 
									
										
										
										
											2017-05-01 21:51:38 +02:00
										 |  |  |              printf_hex(hash_buffer, w); | 
					
						
							| 
									
										
										
										
											2017-04-23 17:32:21 +02:00
										 |  |  |              printf(" *%s\n", argv[z]); | 
					
						
							| 
									
										
										
										
											2003-03-03 00:59:24 +00:00
										 |  |  |          } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    return EXIT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-09 00:08:13 +00:00
										 |  |  | /* $Source$ */ | 
					
						
							|  |  |  | /* $Revision$ */ | 
					
						
							|  |  |  | /* $Date$ */ |