1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71#define FORCE_FLAGS
72#define FOR_md5sum
73#include "toys.h"
74
75#if CFG_TOYBOX_LIBCRYPTO
76#include <openssl/md5.h>
77#include <openssl/sha.h>
78#else
79typedef int SHA512_CTX;
80#endif
81
82GLOBALS(
83 int sawline;
84 unsigned *rconsttable32;
85 unsigned long long *rconsttable64;
86
87
88 unsigned long long count, overflow;
89 union {
90 char c[128];
91 unsigned i32[16];
92 unsigned long long i64[16];
93 } state, buffer;
94)
95
96
97#if ! CFG_TOYBOX_FLOAT
98static const unsigned md5nofloat[64] = {
99 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
100 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
101 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
102 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
103 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
104 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
105 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
106 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
107 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
108 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
109 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
110};
111#else
112#define md5nofloat 0
113#endif
114static unsigned long long sha512nofloat[80] = {
115
116
117
118 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
119 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
120 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
121 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
122 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
123 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
124 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
125 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
126 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
127 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
128 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
129 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
130 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
131 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
132 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
133 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
134 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
135 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
136 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
137 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
138 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
139 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
140 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
141 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
142 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
143 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
144 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
145};
146
147static const unsigned sha1rconsts[] = {
148 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
149};
150
151
152#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
153#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
154#define ror64(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits))))
155
156
157
158static void md5_transform(void)
159{
160 unsigned x[4], *b = TT.buffer.i32;
161 int i;
162
163 for (i = 0; i<4; i++) x[i] = TT.state.i32[i];
164 for (i = 0; i<64; i++) {
165 unsigned in, a, rot, temp;
166
167 a = (-i)&3;
168 if (i<16) {
169 in = i;
170 rot = 7+(5*(i&3));
171 temp = x[(a+1)&3];
172 temp = (temp & x[(a+2)&3]) | ((~temp) & x[(a+3)&3]);
173 } else if (i<32) {
174 in = (1+(5*i))&15;
175 temp = (i&3)+1;
176 rot = temp*5;
177 if (temp&2) rot--;
178 temp = x[(a+3)&3];
179 temp = (x[(a+1)&3] & temp) | (x[(a+2)&3] & ~temp);
180 } else if (i<48) {
181 in = (5+(3*(i&15)))&15;
182 rot = i&3;
183 rot = 4+(5*rot)+((rot+1)&6);
184 temp = x[(a+1)&3] ^ x[(a+2)&3] ^ x[(a+3)&3];
185 } else {
186 in = (7*(i&15))&15;
187 rot = (i&3)+1;
188 rot = (5*rot)+(((rot+2)&2)>>1);
189 temp = x[(a+2)&3] ^ (x[(a+1)&3] | ~x[(a+3)&3]);
190 }
191 temp += x[a] + SWAP_LE32(b[in]) + TT.rconsttable32[i];
192 x[a] = x[(a+1)&3] + ((temp<<rot) | (temp>>(32-rot)));
193 }
194 for (i = 0; i<4; i++) TT.state.i32[i] += x[i];
195}
196
197
198
199static void sha1_transform(void)
200{
201 int i, j, k, count;
202 unsigned *block = TT.buffer.i32, oldstate[5], *rot[5], *temp, work;
203
204
205 for (i = 0; i<5; i++) {
206 oldstate[i] = TT.state.i32[i];
207 rot[i] = TT.state.i32 + i;
208 }
209 if (IS_BIG_ENDIAN) for (i = 0; i<16; i++) block[i] = SWAP_LE32(block[i]);
210
211
212 for (i = count = 0; i<4; i++) {
213 for (j = 0; j<20; j++) {
214 work = *rot[2] ^ *rot[3];
215 if (!i) work = (work & *rot[1]) ^ *rot[3];
216 else {
217 if (i==2) work = ((*rot[1]|*rot[2])&*rot[3])|(*rot[1]&*rot[2]);
218 else work ^= *rot[1];
219 }
220
221 if (!i && j<16)
222 work += block[count] = (ror(block[count],8)&0xFF00FF00)
223 | (rol(block[count],8)&0x00FF00FF);
224 else
225 work += block[count&15] = rol(block[(count+13)&15]
226 ^ block[(count+8)&15] ^ block[(count+2)&15] ^ block[count&15], 1);
227 *rot[4] += work + rol(*rot[0],5) + sha1rconsts[i];
228 *rot[1] = rol(*rot[1],30);
229
230
231 temp = rot[4];
232 for (k = 4; k; k--) rot[k] = rot[k-1];
233 *rot = temp;
234 count++;
235 }
236 }
237
238 for (i = 0; i<5; i++) TT.state.i32[i] += oldstate[i];
239}
240
241static void sha2_32_transform(void)
242{
243 unsigned block[64], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
244 int i;
245
246 for (i = 0; i<16; i++) block[i] = SWAP_BE32(TT.buffer.i32[i]);
247
248
249 for (i = 16; i<64; i++) {
250 s0 = ror(block[i-15], 7) ^ ror(block[i-15], 18) ^ (block[i-15] >> 3);
251 s1 = ror(block[i-2], 17) ^ ror(block[i-2], 19) ^ (block[i-2] >> 10);
252 block[i] = block[i-16] + s0 + block[i-7] + s1;
253 }
254
255 for (i = 0; i<8; i++) rot[i] = TT.state.i32[i];
256
257 for (i = 0; i<64; i++) {
258 S1 = ror(rot[4],6) ^ ror(rot[4],11) ^ ror(rot[4], 25);
259 ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
260 temp1 = rot[7] + S1 + ch + TT.rconsttable32[i] + block[i];
261 S0 = ror(rot[0],2) ^ ror(rot[0],13) ^ ror(rot[0], 22);
262 maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
263 temp2 = S0 + maj;
264 memmove(rot+1, rot, 28);
265 rot[4] += temp1;
266 rot[0] = temp1 + temp2;
267 }
268
269
270 for (i = 0; i<8; i++) TT.state.i32[i] += rot[i];
271}
272
273static void sha2_64_transform(void)
274{
275 unsigned long long block[80], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
276 int i;
277
278 for (i=0; i<16; i++) block[i] = SWAP_BE64(TT.buffer.i64[i]);
279
280
281 for (i = 16; i<80; i++) {
282 s0 = ror64(block[i-15], 1) ^ ror64(block[i-15], 8) ^ (block[i-15] >> 7);
283 s1 = ror64(block[i-2], 19) ^ ror64(block[i-2], 61) ^ (block[i-2] >> 6);
284 block[i] = block[i-16] + s0 + block[i-7] + s1;
285 }
286
287 for (i = 0; i<8; i++) rot[i] = TT.state.i64[i];
288
289 for (i = 0; i<80; i++) {
290 S1 = ror64(rot[4],14) ^ ror64(rot[4],18) ^ ror64(rot[4], 41);
291 ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
292 temp1 = rot[7] + S1 + ch + TT.rconsttable64[i] + block[i];
293 S0 = ror64(rot[0],28) ^ ror64(rot[0],34) ^ ror64(rot[0], 39);
294 maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
295 temp2 = S0 + maj;
296 memmove(rot+1, rot, 56);
297 rot[4] += temp1;
298 rot[0] = temp1 + temp2;
299 }
300
301
302 for (i=0; i<8; i++) TT.state.i64[i] += rot[i];
303}
304
305
306
307static void hash_update(char *data, unsigned int len, void (*transform)(void),
308 int chunksize)
309{
310 unsigned int i, j;
311
312 j = TT.count & (chunksize - 1);
313 if (TT.count+len<TT.count) TT.overflow++;
314 TT.count += len;
315
316 for (;;) {
317
318 i = chunksize - j;
319 if (i>len) i = len;
320 memcpy(TT.buffer.c+j, data, i);
321 if (j+i != chunksize) break;
322
323
324 transform();
325 j=0;
326 data += i;
327 len -= i;
328 }
329}
330
331
332#define HASH_INIT(name, prefix) { name, (void *)prefix##_Init, \
333 (void *)prefix##_Update, (void *)prefix##_Final, \
334 prefix##_DIGEST_LENGTH, }
335#define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
336
337
338static void do_lib_hash(int fd, char *name)
339{
340
341 SHA512_CTX ctx;
342 struct hash {
343 char *name;
344 int (*init)(void *);
345 int (*update)(void *, void *, size_t);
346 int (*final)(void *, void *);
347 int digest_length;
348 } algorithms[] = {
349 USE_TOYBOX_LIBCRYPTO(
350 USE_MD5SUM(HASH_INIT("md5sum", MD5),)
351 USE_SHA1SUM(HASH_INIT("sha1sum", SHA1),)
352 USE_SHA224SUM(HASH_INIT("sha224sum", SHA224),)
353 USE_SHA256SUM(HASH_INIT("sha256sum", SHA256),)
354 USE_SHA384SUM(HASH_INIT("sha384sum", SHA384),)
355 USE_SHA512SUM(HASH_INIT("sha512sum", SHA512),)
356 )
357 }, * hash;
358 int i;
359
360
361 for (i = 0; i<ARRAY_LEN(algorithms); i++)
362 if (!strcmp(toys.which->name, algorithms[i].name)) break;
363 hash = algorithms+i;
364
365 hash->init(&ctx);
366 for (;;) {
367 i = read(fd, toybuf, sizeof(toybuf));
368 if (i<1) break;
369 hash->update(&ctx, toybuf, i);
370 }
371 hash->final(toybuf+128, &ctx);
372
373 for (i = 0; i<hash->digest_length; i++)
374 sprintf(toybuf+2*i, "%02x", toybuf[i+128]);
375}
376
377static void do_builtin_hash(int fd, char *name)
378{
379 unsigned long long count[2];
380 int i, chunksize, digestlen, method;
381 volatile char *pp;
382 void (*transform)(void);
383 char buf;
384
385
386 method = stridx("us2581", toys.which->name[4]);
387
388
389 transform = (void *[]){md5_transform, sha1_transform, sha2_32_transform,
390 sha2_32_transform, sha2_64_transform, sha2_64_transform}[method];
391 digestlen = (char []){16, 20, 28, 32, 48, 64}[method];
392 chunksize = 64<<(method>=4);
393 if (method<=1)
394 memcpy(TT.state.i32, (unsigned []){0x67452301, 0xEFCDAB89, 0x98BADCFE,
395 0x10325476, 0xC3D2E1F0}, 20);
396 else if (method==2)
397 memcpy(TT.state.i32, (unsigned []){0xc1059ed8, 0x367cd507, 0x3070dd17,
398 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}, 32);
399 else if (method==3)
400 memcpy(TT.state.i32, (unsigned []){0x6a09e667, 0xbb67ae85, 0x3c6ef372,
401 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, 32);
402 else if (method==4)
403 memcpy(TT.state.i64, (unsigned long long []){0xcbbb9d5dc1059ed8,
404 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
405 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7,
406 0x47b5481dbefa4fa4}, 64);
407 else memcpy(TT.state.i64, (unsigned long long []){0x6a09e667f3bcc908,
408 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
409 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b,
410 0x5be0cd19137e2179}, 64);
411
412 TT.count = 0;
413 for (;;) {
414 i = read(fd, toybuf, sizeof(toybuf));
415 if (i<1) break;
416 hash_update(toybuf, i, transform, chunksize);
417 }
418
419
420
421
422
423
424
425 buf = 0x80;
426 count[0] = (TT.overflow<<3)+(TT.count>>61);
427 count[1] = TT.count<<3;
428 for (i = 0; i<2; i++)
429 count[i] = !method ? SWAP_LE64(count[i]) : SWAP_BE64(count[i]);
430 i = 8<<(method>=4);
431 do {
432 hash_update(&buf, 1, transform, chunksize);
433 buf = 0;
434 } while ((TT.count&(chunksize-1)) != chunksize-i);
435 hash_update((void *)(count+(method<4)), i, transform, chunksize);
436
437
438 if (method>=4) for (i=0; i<digestlen/8; i++)
439 sprintf(toybuf+16*i, "%016llx", TT.state.i64[i]);
440 else for (i=0; i<digestlen/4; i++)
441 sprintf(toybuf+8*i, "%08x",
442 !method ? bswap_32(TT.state.i32[i]) : TT.state.i32[i]);
443
444
445 i = sizeof(struct md5sum_data)-offsetof(struct md5sum_data, state.i64);
446 for (pp = (void *)TT.state.i64; i; i--) *pp++ = 0;
447 pp = toybuf+strlen(toybuf)+1;
448 for (i = sizeof(toybuf)-(pp-toybuf); i; i--) *pp++ = 0;
449}
450
451
452
453static void do_hash(int fd, char *name)
454{
455 if (CFG_TOYBOX_LIBCRYPTO) do_lib_hash(fd, name);
456 else do_builtin_hash(fd, name);
457
458 if (name) printf("%s %s\n"+4*!!FLAG(b), toybuf, name);
459}
460
461static void do_c_line(char *line)
462{
463 int space = 0, fail = 0, fd;
464 char *name;
465
466 for (name = line; *name; name++) {
467 if (isspace(*name)) {
468 space++;
469 *name = 0;
470 } else if (space) break;
471 }
472 if (!space || !*line || !*name) return error_msg("bad line %s", line);
473
474 fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY);
475
476 TT.sawline = 1;
477 if (fd==-1) {
478 perror_msg_raw(name);
479 *toybuf = 0;
480 } else do_hash(fd, 0);
481 if (strcasecmp(line, toybuf)) toys.exitval = fail = 1;
482 if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK");
483 if (fd>0) close(fd);
484}
485
486
487static void do_c_file(char *name)
488{
489 FILE *fp = !strcmp(name, "-") ? stdin : fopen(name, "r");
490 char *line;
491
492 if (!fp) return perror_msg_raw(name);
493
494 TT.sawline = 0;
495
496 for (;;) {
497 if (!(line = xgetline(fp))) break;
498 do_c_line(line);
499 free(line);
500 }
501 if (fp!=stdin) fclose(fp);
502
503 if (!TT.sawline) error_msg("%s: no lines", name);
504}
505
506void md5sum_main(void)
507{
508 int i;
509
510
511
512 if (!CFG_TOYBOX_LIBCRYPTO) {
513 if (*toys.which->name == 'm') {
514 if (CFG_TOYBOX_FLOAT) {
515 TT.rconsttable32 = xmalloc(64*4);
516 for (i = 0; i<64; i++) TT.rconsttable32[i] = fabs(sin(i+1))*(1LL<<32);
517 } else TT.rconsttable32 = md5nofloat;
518 } else if (toys.which->name[3] == '2') {
519 TT.rconsttable32 = xmalloc(64*4);
520 for (i=0; i<64; i++) TT.rconsttable32[i] = sha512nofloat[i] >> 32;
521 } else TT.rconsttable64 = sha512nofloat;
522 }
523
524 if (FLAG(c)) for (i = 0; toys.optargs[i]; i++) do_c_file(toys.optargs[i]);
525 else {
526 if (FLAG(s)) error_exit("-s only with -c");
527 loopfiles(toys.optargs, do_hash);
528 }
529}
530