• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* md5sum.c - Calculate hashes md5, sha1, sha224, sha256, sha384, sha512.
2  *
3  * Copyright 2012, 2021 Rob Landley <rob@landley.net>
4  *
5  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/md5sum.html
6  * and http://www.ietf.org/rfc/rfc1321.txt
7  * and http://www.ietf.org/rfc/rfc4634.txt
8  *
9  * They're combined this way to share infrastructure, and because md5sum is
10  * a LSB standard command (but sha1sum and newer hashes are a good idea,
11  * see http://valerieaurora.org/hash.html).
12  *
13  * We optionally use openssl (or equivalent) to access assembly optimized
14  * versions of these functions, but provide a built-in version to reduce
15  * required dependencies.
16  *
17  * coreutils supports --status but not -s, busybox supports -s but not --status
18 
19 USE_MD5SUM(NEWTOY(md5sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
20 USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
21 USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
22 USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
23 USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
24 USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
25 
26 config MD5SUM
27   bool "md5sum"
28   default y
29   help
30     usage: ???sum [-bcs] [FILE]...
31 
32     Calculate hash for each input file, reading from stdin if none, writing
33     hexadecimal digits to stdout for each input file (md5=32 hex digits,
34     sha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.
35 
36     -b	Brief (hash only, no filename)
37     -c	Check each line of each FILE is the same hash+filename we'd output
38     -s	No output, exit status 0 if all hashes match, 1 otherwise
39 
40 config SHA1SUM
41   bool "sha1sum"
42   default y
43   help
44     See md5sum
45 
46 config SHA224SUM
47   bool "sha224sum"
48   default y
49   help
50     See md5sum
51 
52 config SHA256SUM
53   bool "sha256sum"
54   default y
55   help
56     See md5sum
57 
58 config SHA384SUM
59   bool "sha384sum"
60   default y
61   help
62     See md5sum
63 
64 config SHA512SUM
65   bool "sha512sum"
66   default y
67   help
68     See md5sum
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
79 typedef int SHA512_CTX;
80 #endif
81 
82 GLOBALS(
83   int sawline;
84   unsigned *rconsttable32;
85   unsigned long long *rconsttable64; // for sha384,sha512
86 
87   // Crypto variables blanked after summing
88   unsigned long long count, overflow;
89   union {
90     char c[128]; // bytes, 1024 bits
91     unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
92     unsigned long long i64[16]; // 1024 bits for sha384,sha512
93   } state, buffer;
94 )
95 
96 // Round constants. Static table for when we haven't got floating point support
97 #if ! CFG_TOYBOX_FLOAT
98 static 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
114 static unsigned long long sha512nofloat[80] = {
115   // we cannot calculate these 64-bit values using the readily
116   // available floating point data types and math functions,
117   // so we always use this lookup table (80 * 8 bytes)
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 // sha1 needs only 4 round constant values, so prefer precomputed
147 static const unsigned sha1rconsts[] = {
148   0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
149 };
150 
151 // bit rotations
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 // Mix next 64 bytes of data into md5 hash
157 
md5_transform(void)158 static 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 // Mix next 64 bytes of data into sha1 hash.
198 
sha1_transform(void)199 static 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   // Copy context->state.i32[] to working vars
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   // 4 rounds of 20 operations each.
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       // Rotate by one for next time.
231       temp = rot[4];
232       for (k = 4; k; k--) rot[k] = rot[k-1];
233       *rot = temp;
234       count++;
235     }
236   }
237   // Add the previous values of state.i32[]
238   for (i = 0; i<5; i++) TT.state.i32[i] += oldstate[i];
239 }
240 
sha2_32_transform(void)241 static 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   // Extend the message schedule array beyond first 16 words
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   // Copy context->state.i32[] to working vars
255   for (i = 0; i<8; i++) rot[i] = TT.state.i32[i];
256   // 64 rounds
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   // Add the previous values of state.i32[]
270   for (i = 0; i<8; i++) TT.state.i32[i] += rot[i];
271 }
272 
sha2_64_transform(void)273 static 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   // Extend the message schedule array beyond first 16 words
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   // Copy context->state.i64[] to working vars
287   for (i = 0; i<8; i++) rot[i] = TT.state.i64[i];
288   // 80 rounds
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   // Add the previous values of state.i64[]
302   for (i=0; i<8; i++) TT.state.i64[i] += rot[i];
303 }
304 
305 // Fill the 64/128-byte (512/1024-bit) working buffer and call transform() when full.
306 
hash_update(char * data,unsigned int len,void (* transform)(void),int chunksize)307 static 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     // Grab next chunk of data, return if it's not enough to process a frame
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     // Process a frame
324     transform();
325     j=0;
326     data += i;
327     len -= i;
328   }
329 }
330 
331 // Initialize array tersely
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 // Call the assembly optimized library code when CFG_TOYBOX_LIBCRYPTO
do_lib_hash(int fd,char * name)338 static void do_lib_hash(int fd, char *name)
339 {
340   // Largest context
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   // This should never NOT match, so no need to check
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 
do_builtin_hash(int fd,char * name)377 static 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   // md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum
386   method = stridx("us2581", toys.which->name[4]);
387 
388   // select hash type
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   // End the message by appending a "1" bit to the data, ending with the
420   // message size (in bits, big endian), and adding enough zero bits in
421   // between to pad to the end of the next frame.
422   //
423   // Since our input up to now has been in whole bytes, we can deal with
424   // bytes here too. sha384 and 512 use 128 bit counter, so track overflow.
425   buf = 0x80;
426   count[0] = (TT.overflow<<3)+(TT.count>>61);
427   count[1] = TT.count<<3; // convert to bits
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   // write digest to toybuf
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   // Wipe variables. Cryptographer paranoia. Avoid "optimizing" out memset
444   // by looping on a volatile pointer.
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 // Callback for loopfiles()
452 // Call builtin or lib hash function, then display output if necessary
do_hash(int fd,char * name)453 static 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 
do_c_line(char * line)461 static 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 // Used instead of loopfiles_line to report error on files containing no hashes.
do_c_file(char * name)487 static 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 
md5sum_main(void)506 void md5sum_main(void)
507 {
508   int i;
509 
510   // Calculate table if we have floating point. Static version should drop
511   // out at compile time when we don't need it.
512   if (!CFG_TOYBOX_LIBCRYPTO) {
513     if (*toys.which->name == 'm') { // MD5
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') { // sha224, sha256
519       TT.rconsttable32 = xmalloc(64*4);
520       for (i=0; i<64; i++) TT.rconsttable32[i] = sha512nofloat[i] >> 32;
521     } else TT.rconsttable64 = sha512nofloat; // sha384, sha512
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