aboutsummaryrefslogtreecommitdiff
path: root/coreutils/md5_sha1_sum.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/md5_sha1_sum.c')
-rw-r--r--coreutils/md5_sha1_sum.c145
1 files changed, 120 insertions, 25 deletions
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 1a5342e87..783f44027 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -5,6 +5,60 @@
5 * 5 *
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */ 7 */
8//config:config MD5SUM
9//config: bool "md5sum"
10//config: default y
11//config: help
12//config: md5sum is used to print or check MD5 checksums.
13//config:
14//config:config SHA1SUM
15//config: bool "sha1sum"
16//config: default y
17//config: help
18//config: Compute and check SHA1 message digest
19//config:
20//config:config SHA256SUM
21//config: bool "sha256sum"
22//config: default y
23//config: help
24//config: Compute and check SHA256 message digest
25//config:
26//config:config SHA512SUM
27//config: bool "sha512sum"
28//config: default y
29//config: help
30//config: Compute and check SHA512 message digest
31//config:
32//config:config SHA3SUM
33//config: bool "sha3sum"
34//config: default y
35//config: help
36//config: Compute and check SHA3 message digest
37//config:
38//config:comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
39//config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
40//config:
41//config:config FEATURE_MD5_SHA1_SUM_CHECK
42//config: bool "Enable -c, -s and -w options"
43//config: default y
44//config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
45//config: help
46//config: Enabling the -c options allows files to be checked
47//config: against pre-calculated hash values.
48//config:
49//config: -s and -w are useful options when verifying checksums.
50
51//applet:IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum))
52//applet:IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum))
53//applet:IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum))
54//applet:IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum))
55//applet:IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum))
56
57//kbuild:lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o
58//kbuild:lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o
59//kbuild:lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
60//kbuild:lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
61//kbuild:lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o
8 62
9//usage:#define md5sum_trivial_usage 63//usage:#define md5sum_trivial_usage
10//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." 64//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
@@ -57,15 +111,20 @@
57//usage: ) 111//usage: )
58//usage: 112//usage:
59//usage:#define sha3sum_trivial_usage 113//usage:#define sha3sum_trivial_usage
60//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." 114//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[-a BITS] [FILE]..."
61//usage:#define sha3sum_full_usage "\n\n" 115//usage:#define sha3sum_full_usage "\n\n"
62//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums" 116//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3 checksums"
63//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" 117//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
64//usage: "\n -c Check sums against list in FILEs" 118//usage: "\n -c Check sums against list in FILEs"
65//usage: "\n -s Don't output anything, status code shows success" 119//usage: "\n -s Don't output anything, status code shows success"
66//usage: "\n -w Warn about improperly formatted checksum lines" 120//usage: "\n -w Warn about improperly formatted checksum lines"
121//usage: "\n -a BITS 224 (default), 256, 384, 512"
67//usage: ) 122//usage: )
68 123
124//FIXME: GNU coreutils 8.25 has no -s option, it has only these two long opts:
125// --quiet don't print OK for each successfully verified file
126// --status don't output anything, status code shows success
127
69#include "libbb.h" 128#include "libbb.h"
70 129
71/* This is a NOEXEC applet. Be very careful! */ 130/* This is a NOEXEC applet. Be very careful! */
@@ -93,7 +152,10 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
93 return (unsigned char *)hex_value; 152 return (unsigned char *)hex_value;
94} 153}
95 154
96static uint8_t *hash_file(const char *filename) 155#if !ENABLE_SHA3SUM
156# define hash_file(f,w) hash_file(f)
157#endif
158static uint8_t *hash_file(const char *filename, unsigned sha3_width)
97{ 159{
98 int src_fd, hash_len, count; 160 int src_fd, hash_len, count;
99 union _ctx_ { 161 union _ctx_ {
@@ -121,27 +183,47 @@ static uint8_t *hash_file(const char *filename)
121 update = (void*)md5_hash; 183 update = (void*)md5_hash;
122 final = (void*)md5_end; 184 final = (void*)md5_end;
123 hash_len = 16; 185 hash_len = 16;
124 } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { 186 }
187 else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) {
125 sha1_begin(&context.sha1); 188 sha1_begin(&context.sha1);
126 update = (void*)sha1_hash; 189 update = (void*)sha1_hash;
127 final = (void*)sha1_end; 190 final = (void*)sha1_end;
128 hash_len = 20; 191 hash_len = 20;
129 } else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { 192 }
193 else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) {
130 sha256_begin(&context.sha256); 194 sha256_begin(&context.sha256);
131 update = (void*)sha256_hash; 195 update = (void*)sha256_hash;
132 final = (void*)sha256_end; 196 final = (void*)sha256_end;
133 hash_len = 32; 197 hash_len = 32;
134 } else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { 198 }
199 else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) {
135 sha512_begin(&context.sha512); 200 sha512_begin(&context.sha512);
136 update = (void*)sha512_hash; 201 update = (void*)sha512_hash;
137 final = (void*)sha512_end; 202 final = (void*)sha512_end;
138 hash_len = 64; 203 hash_len = 64;
139 } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { 204 }
205#if ENABLE_SHA3SUM
206 else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
140 sha3_begin(&context.sha3); 207 sha3_begin(&context.sha3);
141 update = (void*)sha3_hash; 208 update = (void*)sha3_hash;
142 final = (void*)sha3_end; 209 final = (void*)sha3_end;
143 hash_len = 64; 210 /*
144 } else { 211 * Should support 224, 256, 384, 512.
212 * We allow any value which does not blow the algorithm up.
213 */
214 if (sha3_width >= 1600/2 /* input block can't be <= 0 */
215 || sha3_width == 0 /* hash len can't be 0 */
216 || (sha3_width & 0x1f) /* should be multiple of 32 */
217 /* (because input uses up to 8 byte wide word XORs. 32/4=8) */
218 ) {
219 bb_error_msg_and_die("bad -a%u", sha3_width);
220 }
221 sha3_width /= 4;
222 context.sha3.input_block_bytes = 1600/8 - sha3_width;
223 hash_len = sha3_width/2;
224 }
225#endif
226 else {
145 xfunc_die(); /* can't reach this */ 227 xfunc_die(); /* can't reach this */
146 } 228 }
147 229
@@ -172,28 +254,33 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
172{ 254{
173 int return_value = EXIT_SUCCESS; 255 int return_value = EXIT_SUCCESS;
174 unsigned flags; 256 unsigned flags;
257#if ENABLE_SHA3SUM
258 unsigned sha3_width = 224;
259#endif
175 260
176 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { 261 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) {
262 /* -s and -w require -c */
263 opt_complementary = "s?c:w?c";
177 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ 264 /* -b "binary", -t "text" are ignored (shaNNNsum compat) */
178 flags = getopt32(argv, "scwbt"); 265#if ENABLE_SHA3SUM
179 argv += optind; 266 if (applet_name[3] == HASH_SHA3)
180 //argc -= optind; 267 flags = getopt32(argv, "scwbta:+", &sha3_width);
268 else
269#endif
270 flags = getopt32(argv, "scwbt");
181 } else { 271 } else {
182 argv += 1; 272#if ENABLE_SHA3SUM
183 //argc -= 1; 273 if (applet_name[3] == HASH_SHA3)
274 getopt32(argv, "a:+", &sha3_width);
275 else
276#endif
277 getopt32(argv, "");
184 } 278 }
279 argv += optind;
280 //argc -= optind;
185 if (!*argv) 281 if (!*argv)
186 *--argv = (char*)"-"; 282 *--argv = (char*)"-";
187 283
188 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
189 if (flags & FLAG_SILENT) {
190 bb_error_msg_and_die("-%c is meaningful only with -c", 's');
191 }
192 if (flags & FLAG_WARN) {
193 bb_error_msg_and_die("-%c is meaningful only with -c", 'w');
194 }
195 }
196
197 do { 284 do {
198 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { 285 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
199 FILE *pre_computed_stream; 286 FILE *pre_computed_stream;
@@ -225,7 +312,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
225 *filename_ptr = '\0'; 312 *filename_ptr = '\0';
226 filename_ptr += 2; 313 filename_ptr += 2;
227 314
228 hash_value = hash_file(filename_ptr); 315 hash_value = hash_file(filename_ptr, sha3_width);
229 316
230 if (hash_value && (strcmp((char*)hash_value, line) == 0)) { 317 if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
231 if (!(flags & FLAG_SILENT)) 318 if (!(flags & FLAG_SILENT))
@@ -244,9 +331,17 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
244 bb_error_msg("WARNING: %d of %d computed checksums did NOT match", 331 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
245 count_failed, count_total); 332 count_failed, count_total);
246 } 333 }
334 if (count_total == 0) {
335 return_value = EXIT_FAILURE;
336 /*
337 * md5sum from GNU coreutils 8.25 says:
338 * md5sum: <FILE>: no properly formatted MD5 checksum lines found
339 */
340 bb_error_msg("%s: no checksum lines found", *argv);
341 }
247 fclose_if_not_stdin(pre_computed_stream); 342 fclose_if_not_stdin(pre_computed_stream);
248 } else { 343 } else {
249 uint8_t *hash_value = hash_file(*argv); 344 uint8_t *hash_value = hash_file(*argv, sha3_width);
250 if (hash_value == NULL) { 345 if (hash_value == NULL) {
251 return_value = EXIT_FAILURE; 346 return_value = EXIT_FAILURE;
252 } else { 347 } else {