comparison libtomcrypt/demos/hashsum.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 */
9
1 /* 10 /*
2 * Written by Daniel Richards <[email protected]> 6/7/2002 11 * Written by Daniel Richards <[email protected]> 6/7/2002
3 * hash.c: This app uses libtomcrypt to hash either stdin or a file 12 * hash.c: This app uses libtomcrypt to hash either stdin or a file
4 * This file is Public Domain. No rights are reserved. 13 * This file is Public Domain. No rights are reserved.
5 * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt' 14 * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt'
7 * more functions ;) 16 * more functions ;)
8 */ 17 */
9 18
10 #include <tomcrypt.h> 19 #include <tomcrypt.h>
11 20
12 int errno; 21 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
13 22 #include <libgen.h>
14 void register_algs(); 23 #else
24 #define basename(x) x
25 #endif
26
27 #if !defined(PATH_MAX) && defined(_MSC_VER)
28 #include <windows.h>
29 #define PATH_MAX MAX_PATH
30 #endif
31
32 /* thanks http://stackoverflow.com/a/8198009 */
33 #define _base(x) ((x >= '0' && x <= '9') ? '0' : \
34 (x >= 'a' && x <= 'f') ? 'a' - 10 : \
35 (x >= 'A' && x <= 'F') ? 'A' - 10 : \
36 '\255')
37 #define HEXOF(x) (x - _base(x))
38
39 static char* hashsum;
40
41 static void cleanup(void)
42 {
43 free(hashsum);
44 }
45
46 static void die(int status)
47 {
48 unsigned long w, x;
49 FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
50 fprintf(o, "usage: %s -a algorithm [-c] [file...]\n\n", hashsum);
51 fprintf(o, "\t-c\tCheck the hash(es) of the file(s) written in [file].\n");
52 fprintf(o, "\t\t(-a not required)\n");
53 fprintf(o, "\nAlgorithms:\n\t");
54 w = 0;
55 for (x = 0; hash_descriptor[x].name != NULL; x++) {
56 w += fprintf(o, "%-14s", hash_descriptor[x].name);
57 if (w >= 70) {
58 fprintf(o, "\n\t");
59 w = 0;
60 }
61 }
62 if (w != 0) fprintf(o, "\n");
63 exit(status);
64 }
65
66 static void printf_hex(unsigned char* hash_buffer, unsigned long w)
67 {
68 unsigned long x;
69 for (x = 0; x < w; x++) {
70 printf("%02x",hash_buffer[x]);
71 }
72 }
73
74 static void check_file(int argn, int argc, char **argv)
75 {
76 int err, failed, invalid;
77 unsigned char is_buffer[MAXBLOCKSIZE], should_buffer[MAXBLOCKSIZE];
78 char buf[PATH_MAX + (MAXBLOCKSIZE * 3)];
79 /* iterate through all files */
80 while(argn < argc) {
81 char* s;
82 FILE* f = fopen(argv[argn], "rb");
83 if(f == NULL) {
84 int n = snprintf(buf, sizeof(buf), "%s: %s", hashsum, argv[argn]);
85 if (n > 0 && n < (int)sizeof(buf))
86 perror(buf);
87 else
88 perror(argv[argn]);
89 exit(EXIT_FAILURE);
90 }
91 failed = 0;
92 invalid = 0;
93 /* read the file line by line */
94 while((s = fgets(buf, sizeof(buf), f)) != NULL)
95 {
96 int tries, n;
97 unsigned long hash_len, w, x;
98 char* space = strstr(s, " ");
99
100 /* skip lines with comments */
101 if (buf[0] == '#') continue;
102
103 if (space == NULL) {
104 fprintf(stderr, "%s: no properly formatted checksum lines found\n", hashsum);
105 goto ERR;
106 }
107
108 hash_len = space - s;
109 hash_len /= 2;
110
111 if (hash_len > sizeof(should_buffer)) {
112 fprintf(stderr, "%s: hash too long\n", hashsum);
113 goto ERR;
114 }
115
116 /* convert the hex-string back to binary */
117 for (x = 0; x < hash_len; ++x) {
118 should_buffer[x] = HEXOF(s[x*2]) << 4 | HEXOF(s[x*2 + 1]);
119 }
120
121 space++;
122 if (*space != '*') {
123 fprintf(stderr, "%s: unsupported input mode '%c'\n", hashsum, *space);
124 goto ERR;
125 }
126 space++;
127
128 for (n = 0; n < (buf + sizeof(buf)) - space; ++n) {
129 if(iscntrl((int)space[n])) {
130 space[n] = '\0';
131 break;
132 }
133 }
134
135 /* try all hash algorithms that have the appropriate hash size */
136 tries = 0;
137 for (x = 0; hash_descriptor[x].name != NULL; ++x) {
138 if (hash_descriptor[x].hashsize == hash_len) {
139 tries++;
140 w = sizeof(is_buffer);
141 if ((err = hash_file(x, space, is_buffer, &w)) != CRYPT_OK) {
142 fprintf(stderr, "%s: File hash error: %s: %s\n", hashsum, space, error_to_string(err));
143 ERR:
144 fclose(f);
145 exit(EXIT_FAILURE);
146 }
147 if(XMEMCMP(should_buffer, is_buffer, w) == 0) {
148 printf("%s: OK\n", space);
149 break;
150 }
151 }
152 } /* for */
153 if (hash_descriptor[x].name == NULL) {
154 if(tries > 0) {
155 printf("%s: FAILED\n", space);
156 failed++;
157 }
158 else {
159 invalid++;
160 }
161 }
162 } /* while */
163 fclose(f);
164 if(invalid) {
165 fprintf(stderr, "%s: WARNING: %d %s is improperly formatted\n", hashsum, invalid, invalid > 1?"lines":"line");
166 }
167 if(failed) {
168 fprintf(stderr, "%s: WARNING: %d computed %s did NOT match\n", hashsum, failed, failed > 1?"checksums":"checksum");
169 }
170 argn++;
171 }
172 exit(EXIT_SUCCESS);
173 }
15 174
16 int main(int argc, char **argv) 175 int main(int argc, char **argv)
17 { 176 {
18 int idx, x, z; 177 int idxs[TAB_SIZE], idx, check, y, z, err, argn;
19 unsigned long w; 178 unsigned long w, x;
20 unsigned char hash_buffer[MAXBLOCKSIZE]; 179 unsigned char hash_buffer[MAXBLOCKSIZE];
21 hash_state md; 180
181 hashsum = strdup(basename(argv[0]));
182 atexit(cleanup);
22 183
23 /* You need to register algorithms before using them */ 184 /* You need to register algorithms before using them */
24 register_algs(); 185 register_all_ciphers();
25 if (argc < 2) { 186 register_all_hashes();
26 printf("usage: ./hash algorithm file [file ...]\n"); 187 if (argc > 1 && (strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0)) {
27 printf("Algorithms:\n"); 188 die(EXIT_SUCCESS);
28 for (x = 0; hash_descriptor[x].name != NULL; x++) { 189 }
29 printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID); 190 if (argc < 3) {
30 } 191 die(EXIT_FAILURE);
31 exit(EXIT_SUCCESS); 192 }
32 } 193
33 194 for (x = 0; x < sizeof(idxs)/sizeof(idxs[0]); ++x) {
34 idx = find_hash(argv[1]); 195 idxs[x] = -2;
35 if (idx == -1) { 196 }
36 fprintf(stderr, "\nInvalid hash specified on command line.\n"); 197 argn = 1;
37 return -1; 198 check = 0;
38 } 199 idx = 0;
39 200
40 if (argc == 2) { 201 while(argn < argc){
41 hash_descriptor[idx].init(&md); 202 if(strcmp("-a", argv[argn]) == 0) {
42 do { 203 argn++;
43 x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin); 204 if(argn < argc) {
44 hash_descriptor[idx].process(&md, hash_buffer, x); 205 idxs[idx] = find_hash(argv[argn]);
45 } while (x == sizeof(hash_buffer)); 206 if (idxs[idx] == -1) {
46 hash_descriptor[idx].done(&md, hash_buffer); 207 struct {
47 for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { 208 const char* is;
48 printf("%02x",hash_buffer[x]); 209 const char* should;
49 } 210 } shasum_compat[] =
50 printf(" (stdin)\n"); 211 {
212 #ifdef LTC_SHA1
213 { "1", sha1_desc.name },
214 #endif
215 #ifdef LTC_SHA224
216 { "224", sha224_desc.name },
217 #endif
218 #ifdef LTC_SHA256
219 { "256", sha256_desc.name },
220 #endif
221 #ifdef LTC_SHA384
222 { "384", sha384_desc.name },
223 #endif
224 #ifdef LTC_SHA512
225 { "512", sha512_desc.name },
226 #endif
227 #ifdef LTC_SHA512_224
228 { "512224", sha512_224_desc.name },
229 #endif
230 #ifdef LTC_SHA512_256
231 { "512256", sha512_256_desc.name },
232 #endif
233 { NULL, NULL }
234 };
235 for (x = 0; shasum_compat[x].is != NULL; ++x) {
236 if(XSTRCMP(shasum_compat[x].is, argv[argn]) == 0) {
237 idxs[idx] = find_hash(shasum_compat[x].should);
238 break;
239 }
240 }
241 }
242 if (idxs[idx] == -1) {
243 fprintf(stderr, "%s: Unrecognized algorithm\n", hashsum);
244 die(EXIT_FAILURE);
245 }
246 idx++;
247 if ((size_t)idx >= sizeof(idxs)/sizeof(idxs[0])) {
248 fprintf(stderr, "%s: Too many '-a' options chosen\n", hashsum);
249 die(EXIT_FAILURE);
250 }
251 argn++;
252 continue;
253 }
254 else {
255 die(EXIT_FAILURE);
256 }
257 }
258 if(strcmp("-c", argv[argn]) == 0) {
259 check = 1;
260 argn++;
261 continue;
262 }
263 break;
264 }
265
266 if (check == 1) {
267 check_file(argn, argc, argv);
268 }
269
270 if (argc == argn) {
271 w = sizeof(hash_buffer);
272 if ((err = hash_filehandle(idxs[0], stdin, hash_buffer, &w)) != CRYPT_OK) {
273 fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
274 return EXIT_FAILURE;
275 } else {
276 for (x = 0; x < w; x++) {
277 printf("%02x",hash_buffer[x]);
278 }
279 printf(" *-\n");
280 }
51 } else { 281 } else {
52 for (z = 2; z < argc; z++) { 282 for (z = argn; z < argc; z++) {
53 w = sizeof(hash_buffer); 283 for (y = 0; y < idx; ++y) {
54 if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { 284 w = sizeof(hash_buffer);
55 printf("File hash error: %s\n", error_to_string(errno)); 285 if ((err = hash_file(idxs[y],argv[z],hash_buffer,&w)) != CRYPT_OK) {
56 } else { 286 fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
57 for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { 287 return EXIT_FAILURE;
58 printf("%02x",hash_buffer[x]); 288 } else {
59 } 289 printf_hex(hash_buffer, w);
60 printf(" %s\n", argv[z]); 290 printf(" *%s\n", argv[z]);
291 }
61 } 292 }
62 } 293 }
63 } 294 }
64 return EXIT_SUCCESS; 295 return EXIT_SUCCESS;
65 } 296 }
66 297
67 void register_algs(void) 298 /* ref: $Format:%D$ */
68 { 299 /* git commit: $Format:%H$ */
69 int err; 300 /* commit time: $Format:%ai$ */
70
71 #ifdef LTC_TIGER
72 register_hash (&tiger_desc);
73 #endif
74 #ifdef LTC_MD2
75 register_hash (&md2_desc);
76 #endif
77 #ifdef LTC_MD4
78 register_hash (&md4_desc);
79 #endif
80 #ifdef LTC_MD5
81 register_hash (&md5_desc);
82 #endif
83 #ifdef LTC_SHA1
84 register_hash (&sha1_desc);
85 #endif
86 #ifdef LTC_SHA224
87 register_hash (&sha224_desc);
88 #endif
89 #ifdef LTC_SHA256
90 register_hash (&sha256_desc);
91 #endif
92 #ifdef LTC_SHA384
93 register_hash (&sha384_desc);
94 #endif
95 #ifdef LTC_SHA512
96 register_hash (&sha512_desc);
97 #endif
98 #ifdef LTC_RIPEMD128
99 register_hash (&rmd128_desc);
100 #endif
101 #ifdef LTC_RIPEMD160
102 register_hash (&rmd160_desc);
103 #endif
104 #ifdef LTC_WHIRLPOOL
105 register_hash (&whirlpool_desc);
106 #endif
107 #ifdef LTC_CHC_HASH
108 register_hash(&chc_desc);
109 if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) {
110 printf("chc_register error: %s\n", error_to_string(err));
111 exit(EXIT_FAILURE);
112 }
113 #endif
114
115 }
116
117 /* $Source$ */
118 /* $Revision$ */
119 /* $Date$ */