Mercurial > dropbear
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$ */ |