6
6
* and http://www.ietf.org/rfc/rfc1321.txt
7
7
*
8
8
* They're combined this way to share infrastructure, and because md5sum is
9
- * and LSB standard command, sha1sum is just a good idea.
9
+ * and LSB standard command (but sha1sum and newer hashes are a good idea,
10
+ * see http://valerieaurora.org/hash.html).
11
+ *
12
+ * We optionally use openssl (or equivalent) to access assembly optimized
13
+ * versions of these functions, but provide a built-in version to reduce
14
+ * required dependencies.
10
15
11
16
USE_MD5SUM(NEWTOY(md5sum, "bc*[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
12
17
USE_SHA1SUM(NEWTOY(sha1sum, "bc*[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
18
+ USE_SHA224SUM(OLDTOY(sha224sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN))
19
+ USE_SHA256SUM(OLDTOY(sha256sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN))
20
+ USE_SHA384SUM(OLDTOY(sha384sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN))
21
+ USE_SHA512SUM(OLDTOY(sha512sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN))
13
22
14
23
config MD5SUM
15
24
bool "md5sum"
@@ -18,8 +27,7 @@ config MD5SUM
18
27
usage: md5sum [-b] [-c FILE] [FILE]...
19
28
20
29
Calculate md5 hash for each input file, reading from stdin if none.
21
- Output one hash (16 hex digits) for each input file, followed by
22
- filename.
30
+ Output one hash (32 hex digits) for each input file, followed by filename.
23
31
24
32
-b brief (hash only, no filename)
25
33
-c Check each line of FILE is the same hash+filename we'd output.
@@ -28,19 +36,56 @@ config SHA1SUM
28
36
bool "sha1sum"
29
37
default y
30
38
help
31
- usage: sha1sum [-b] [-c FILE] [FILE]...
39
+ usage: sha?sum [-b] [-c FILE] [FILE]...
32
40
33
- calculate sha1 hash for each input file, reading from stdin if none.
34
- Output one hash (20 hex digits) for each input file, followed by
35
- filename.
41
+ calculate sha hash for each input file, reading from stdin if none. Output
42
+ one hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,
43
+ and 128 for sha512) for each input file, followed by filename.
36
44
37
45
-b brief (hash only, no filename)
38
46
-c Check each line of FILE is the same hash+filename we'd output.
47
+
48
+ config SHA224SUM
49
+ bool "sha224sum"
50
+ default y
51
+ depends on TOYBOX_LIBCRYPTO
52
+ help
53
+ See sha1sum
54
+
55
+ config SHA256SUM
56
+ bool "sha256sum"
57
+ default y
58
+ depends on TOYBOX_LIBCRYPTO
59
+ help
60
+ See sha1sum
61
+
62
+ config SHA384SUM
63
+ bool "sha384sum"
64
+ default y
65
+ depends on TOYBOX_LIBCRYPTO
66
+ help
67
+ See sha1sum
68
+
69
+ config SHA512SUM
70
+ bool "sha512sum"
71
+ default y
72
+ depends on TOYBOX_LIBCRYPTO
73
+ help
74
+ See sha1sum
39
75
*/
40
76
77
+ #define FORCE_FLAGS
41
78
#define FOR_md5sum
42
79
#include "toys.h"
43
80
81
+ #if CFG_TOYBOX_LIBCRYPTO
82
+ #include <openssl/md5.h>
83
+ #include <openssl/sha.h>
84
+ #else
85
+ typedef int MD5_CTX ;
86
+ typedef int SHA_CTX ;
87
+ #endif
88
+
44
89
GLOBALS (
45
90
struct arg_list * c ;
46
91
@@ -192,12 +237,58 @@ static void hash_update(char *data, unsigned int len, void (*transform)(void))
192
237
}
193
238
}
194
239
240
+ // Initialize array tersely
241
+ #define HASH_INIT (name , prefix ) { name, (void *)prefix##_Init, \
242
+ (void *)prefix##_Update, (void *)prefix##_Final, \
243
+ prefix##_DIGEST_LENGTH, }
244
+ #define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
245
+
246
+ // Call the assembly optimized library code when CFG_TOYBOX_LIBCRYPTO
247
+ static void do_lib_hash (int fd , char * name )
248
+ {
249
+ // Largest context
250
+ SHA512_CTX ctx ;
251
+ struct hash {
252
+ char * name ;
253
+ int (* init )(void * );
254
+ int (* update )(void * , void * , size_t );
255
+ int (* final )(void * , void * );
256
+ int digest_length ;
257
+ } algorithms [] = {
258
+ USE_TOYBOX_LIBCRYPTO (
259
+ USE_MD5SUM (HASH_INIT ("md5sum" , MD5 ),)
260
+ USE_SHA1SUM (HASH_INIT ("sha1sum" , SHA1 ),)
261
+ USE_SHA224SUM (HASH_INIT ("sha224sum" , SHA224 ),)
262
+ USE_SHA256SUM (HASH_INIT ("sha256sum" , SHA256 ),)
263
+ USE_SHA384SUM (HASH_INIT ("sha384sum" , SHA384 ),)
264
+ USE_SHA512SUM (HASH_INIT ("sha512sum" , SHA512 ),)
265
+ )
266
+ }, * hash ;
267
+ int i ;
268
+
269
+ // This should never NOT match, so no need to check
270
+ for (i = 0 ; i < ARRAY_LEN (algorithms ); i ++ )
271
+ if (!strcmp (toys .which -> name , algorithms [i ].name )) break ;
272
+ hash = algorithms + i ;
273
+
274
+ hash -> init (& ctx );
275
+ for (;;) {
276
+ i = read (fd , toybuf , sizeof (toybuf ));
277
+ if (i < 1 ) break ;
278
+ hash -> update (& ctx , toybuf , i );
279
+ }
280
+ hash -> final (toybuf + 128 , & ctx );
281
+
282
+ for (i = 0 ; i < hash -> digest_length ; i ++ )
283
+ sprintf (toybuf +2 * i , "%02x" , toybuf [i + 128 ]);
284
+ }
285
+
195
286
// Callback for loopfiles()
196
287
197
- static void do_hash (int fd , char * name )
288
+ static void do_builtin_hash (int fd , char * name )
198
289
{
199
290
uint64_t count ;
200
- int i , sha1 = toys .which -> name [0 ]== 's' ;;
291
+ int i , sha1 = toys .which -> name [0 ]== 's' ;
201
292
char buf ;
202
293
void (* transform )(void );
203
294
@@ -238,15 +329,22 @@ static void do_hash(int fd, char *name)
238
329
sprintf (toybuf + 2 * i , "%02x" , 255 & (TT .state [i >>2 ] >> ((3 - (i & 3 )) * 8 )));
239
330
else for (i = 0 ; i < 4 ; i ++ ) sprintf (toybuf + 8 * i , "%08x" , bswap_32 (TT .state [i ]));
240
331
241
- if (name )
242
- printf ((toys .optflags & FLAG_b ) ? "%s\n" : "%s %s\n" , toybuf , name );
243
-
244
332
// Wipe variables. Cryptographer paranoia.
245
333
memset (TT .state , 0 , sizeof (TT )- ((long )TT .state - (long )& TT ));
246
334
i = strlen (toybuf )+ 1 ;
247
335
memset (toybuf + i , 0 , sizeof (toybuf )- i );
248
336
}
249
337
338
+ // Call builtin or lib hash function, then display output if necessary
339
+ static void do_hash (int fd , char * name )
340
+ {
341
+ if (CFG_TOYBOX_LIBCRYPTO ) do_lib_hash (fd , name );
342
+ else do_builtin_hash (fd ,name );
343
+
344
+ if (name )
345
+ printf ((toys .optflags & FLAG_b ) ? "%s\n" : "%s %s\n" , toybuf , name );
346
+ }
347
+
250
348
static int do_c (char * line , size_t len )
251
349
{
252
350
int space = 0 , fail = 0 ;
0 commit comments