diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-29 14:05:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-29 14:05:25 +0200 |
commit | 71a090f1871f165ebf3c31f733b36aafca71a6b4 (patch) | |
tree | 4f0b38ba12a6e5b80aa829574f999ae1efd9f17a | |
parent | d3d7f085ebf2898b62d4bb75566122c65be96454 (diff) | |
download | busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.tar.gz busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.tar.bz2 busybox-w32-71a090f1871f165ebf3c31f733b36aafca71a6b4.zip |
sha3: fix to conform to final SHA3 padding standard, add -a BITS option
function old new delta
hash_file 331 396 +65
md5_sha1_sum_main 485 538 +53
packed_usage 30423 30464 +41
sha3_begin 17 31 +14
sha3_hash 101 110 +9
sha3_end 41 49 +8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/Config.src | 43 | ||||
-rw-r--r-- | coreutils/Kbuild.src | 5 | ||||
-rw-r--r-- | coreutils/md5_sha1_sum.c | 122 | ||||
-rw-r--r-- | include/applets.src.h | 5 | ||||
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 55 | ||||
-rwxr-xr-x | testsuite/sha3sum.tests | 2 |
7 files changed, 143 insertions, 90 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src index 619c2efe8..b9dde1209 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -328,12 +328,6 @@ config FEATURE_LS_COLOR_IS_DEFAULT | |||
328 | configurable, and the output may not be legible on | 328 | configurable, and the output may not be legible on |
329 | many output screens. | 329 | many output screens. |
330 | 330 | ||
331 | config MD5SUM | ||
332 | bool "md5sum" | ||
333 | default y | ||
334 | help | ||
335 | md5sum is used to print or check MD5 checksums. | ||
336 | |||
337 | config MKDIR | 331 | config MKDIR |
338 | bool "mkdir" | 332 | bool "mkdir" |
339 | default y | 333 | default y |
@@ -458,30 +452,6 @@ config SEQ | |||
458 | help | 452 | help |
459 | print a sequence of numbers | 453 | print a sequence of numbers |
460 | 454 | ||
461 | config SHA1SUM | ||
462 | bool "sha1sum" | ||
463 | default y | ||
464 | help | ||
465 | Compute and check SHA1 message digest | ||
466 | |||
467 | config SHA256SUM | ||
468 | bool "sha256sum" | ||
469 | default y | ||
470 | help | ||
471 | Compute and check SHA256 message digest | ||
472 | |||
473 | config SHA512SUM | ||
474 | bool "sha512sum" | ||
475 | default y | ||
476 | help | ||
477 | Compute and check SHA512 message digest | ||
478 | |||
479 | config SHA3SUM | ||
480 | bool "sha3sum" | ||
481 | default y | ||
482 | help | ||
483 | Compute and check SHA3 (512-bit) message digest | ||
484 | |||
485 | config SLEEP | 455 | config SLEEP |
486 | bool "sleep" | 456 | bool "sleep" |
487 | default y | 457 | default y |
@@ -731,17 +701,4 @@ config FEATURE_HUMAN_READABLE | |||
731 | help | 701 | help |
732 | Allow df, du, and ls to have human readable output. | 702 | Allow df, du, and ls to have human readable output. |
733 | 703 | ||
734 | comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" | ||
735 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM | ||
736 | |||
737 | config FEATURE_MD5_SHA1_SUM_CHECK | ||
738 | bool "Enable -c, -s and -w options" | ||
739 | default y | ||
740 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM | ||
741 | help | ||
742 | Enabling the -c options allows files to be checked | ||
743 | against pre-calculated hash values. | ||
744 | |||
745 | -s and -w are useful options when verifying checksums. | ||
746 | |||
747 | endmenu | 704 | endmenu |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 4ec075ac6..5a64fee35 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
@@ -41,7 +41,6 @@ lib-$(CONFIG_LN) += ln.o | |||
41 | lib-$(CONFIG_LOGNAME) += logname.o | 41 | lib-$(CONFIG_LOGNAME) += logname.o |
42 | lib-$(CONFIG_LS) += ls.o | 42 | lib-$(CONFIG_LS) += ls.o |
43 | lib-$(CONFIG_FTPD) += ls.o | 43 | lib-$(CONFIG_FTPD) += ls.o |
44 | lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o | ||
45 | lib-$(CONFIG_MKDIR) += mkdir.o | 44 | lib-$(CONFIG_MKDIR) += mkdir.o |
46 | lib-$(CONFIG_MKFIFO) += mkfifo.o | 45 | lib-$(CONFIG_MKFIFO) += mkfifo.o |
47 | lib-$(CONFIG_MKNOD) += mknod.o | 46 | lib-$(CONFIG_MKNOD) += mknod.o |
@@ -58,10 +57,6 @@ lib-$(CONFIG_REALPATH) += realpath.o | |||
58 | lib-$(CONFIG_RM) += rm.o | 57 | lib-$(CONFIG_RM) += rm.o |
59 | lib-$(CONFIG_RMDIR) += rmdir.o | 58 | lib-$(CONFIG_RMDIR) += rmdir.o |
60 | lib-$(CONFIG_SEQ) += seq.o | 59 | lib-$(CONFIG_SEQ) += seq.o |
61 | lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o | ||
62 | lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o | ||
63 | lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o | ||
64 | lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o | ||
65 | lib-$(CONFIG_SLEEP) += sleep.o | 60 | lib-$(CONFIG_SLEEP) += sleep.o |
66 | lib-$(CONFIG_SPLIT) += split.o | 61 | lib-$(CONFIG_SPLIT) += split.o |
67 | lib-$(CONFIG_SORT) += sort.o | 62 | lib-$(CONFIG_SORT) += sort.o |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index c0e816ba6..5e017b191 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 (512-bit) 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,13 +111,14 @@ | |||
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 | ||
69 | //FIXME: GNU coreutils 8.25 has no -s option, it has only these two long opts: | 124 | //FIXME: GNU coreutils 8.25 has no -s option, it has only these two long opts: |
@@ -97,7 +152,10 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value, | |||
97 | return (unsigned char *)hex_value; | 152 | return (unsigned char *)hex_value; |
98 | } | 153 | } |
99 | 154 | ||
100 | static uint8_t *hash_file(const char *filename) | 155 | #if !ENABLE_SHA3SUM |
156 | # define hash_file(f,w) hash_file(f) | ||
157 | #endif | ||
158 | static uint8_t *hash_file(const char *filename, unsigned sha3_width) | ||
101 | { | 159 | { |
102 | int src_fd, hash_len, count; | 160 | int src_fd, hash_len, count; |
103 | union _ctx_ { | 161 | union _ctx_ { |
@@ -125,27 +183,47 @@ static uint8_t *hash_file(const char *filename) | |||
125 | update = (void*)md5_hash; | 183 | update = (void*)md5_hash; |
126 | final = (void*)md5_end; | 184 | final = (void*)md5_end; |
127 | hash_len = 16; | 185 | hash_len = 16; |
128 | } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { | 186 | } |
187 | else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { | ||
129 | sha1_begin(&context.sha1); | 188 | sha1_begin(&context.sha1); |
130 | update = (void*)sha1_hash; | 189 | update = (void*)sha1_hash; |
131 | final = (void*)sha1_end; | 190 | final = (void*)sha1_end; |
132 | hash_len = 20; | 191 | hash_len = 20; |
133 | } else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { | 192 | } |
193 | else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { | ||
134 | sha256_begin(&context.sha256); | 194 | sha256_begin(&context.sha256); |
135 | update = (void*)sha256_hash; | 195 | update = (void*)sha256_hash; |
136 | final = (void*)sha256_end; | 196 | final = (void*)sha256_end; |
137 | hash_len = 32; | 197 | hash_len = 32; |
138 | } else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { | 198 | } |
199 | else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { | ||
139 | sha512_begin(&context.sha512); | 200 | sha512_begin(&context.sha512); |
140 | update = (void*)sha512_hash; | 201 | update = (void*)sha512_hash; |
141 | final = (void*)sha512_end; | 202 | final = (void*)sha512_end; |
142 | hash_len = 64; | 203 | hash_len = 64; |
143 | } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { | 204 | } |
205 | #if ENABLE_SHA3SUM | ||
206 | else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { | ||
144 | sha3_begin(&context.sha3); | 207 | sha3_begin(&context.sha3); |
145 | update = (void*)sha3_hash; | 208 | update = (void*)sha3_hash; |
146 | final = (void*)sha3_end; | 209 | final = (void*)sha3_end; |
147 | hash_len = 64; | 210 | /* |
148 | } 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 { | ||
149 | xfunc_die(); /* can't reach this */ | 227 | xfunc_die(); /* can't reach this */ |
150 | } | 228 | } |
151 | 229 | ||
@@ -176,18 +254,30 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
176 | { | 254 | { |
177 | int return_value = EXIT_SUCCESS; | 255 | int return_value = EXIT_SUCCESS; |
178 | unsigned flags; | 256 | unsigned flags; |
257 | #if ENABLE_SHA3SUM | ||
258 | unsigned sha3_width = 224; | ||
259 | #endif | ||
179 | 260 | ||
180 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { | 261 | if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { |
181 | /* -s and -w require -c */ | 262 | /* -s and -w require -c */ |
182 | opt_complementary = "s?c:w?c"; | 263 | opt_complementary = "s?c:w?c"; |
183 | /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ | 264 | /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ |
184 | flags = getopt32(argv, "scwbt"); | 265 | #if ENABLE_SHA3SUM |
185 | argv += optind; | 266 | if (applet_name[3] == HASH_SHA3) |
186 | //argc -= optind; | 267 | flags = getopt32(argv, "scwbta:+", &sha3_width); |
268 | else | ||
269 | #endif | ||
270 | flags = getopt32(argv, "scwbt"); | ||
187 | } else { | 271 | } else { |
188 | argv += 1; | 272 | #if ENABLE_SHA3SUM |
189 | //argc -= 1; | 273 | if (applet_name[3] == HASH_SHA3) |
274 | getopt32(argv, "a:+", &sha3_width); | ||
275 | else | ||
276 | #endif | ||
277 | getopt32(argv, ""); | ||
190 | } | 278 | } |
279 | argv += optind; | ||
280 | //argc -= optind; | ||
191 | if (!*argv) | 281 | if (!*argv) |
192 | *--argv = (char*)"-"; | 282 | *--argv = (char*)"-"; |
193 | 283 | ||
@@ -222,7 +312,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
222 | *filename_ptr = '\0'; | 312 | *filename_ptr = '\0'; |
223 | filename_ptr += 2; | 313 | filename_ptr += 2; |
224 | 314 | ||
225 | hash_value = hash_file(filename_ptr); | 315 | hash_value = hash_file(filename_ptr, sha3_width); |
226 | 316 | ||
227 | if (hash_value && (strcmp((char*)hash_value, line) == 0)) { | 317 | if (hash_value && (strcmp((char*)hash_value, line) == 0)) { |
228 | if (!(flags & FLAG_SILENT)) | 318 | if (!(flags & FLAG_SILENT)) |
@@ -251,7 +341,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
251 | } | 341 | } |
252 | fclose_if_not_stdin(pre_computed_stream); | 342 | fclose_if_not_stdin(pre_computed_stream); |
253 | } else { | 343 | } else { |
254 | uint8_t *hash_value = hash_file(*argv); | 344 | uint8_t *hash_value = hash_file(*argv, sha3_width); |
255 | if (hash_value == NULL) { | 345 | if (hash_value == NULL) { |
256 | return_value = EXIT_FAILURE; | 346 | return_value = EXIT_FAILURE; |
257 | } else { | 347 | } else { |
diff --git a/include/applets.src.h b/include/applets.src.h index 6e1b02fc3..248d539c4 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
@@ -205,7 +205,6 @@ IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) | |||
205 | IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) | 205 | IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) |
206 | IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP)) | 206 | IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP)) |
207 | IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 207 | IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
208 | IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) | ||
209 | IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) | 208 | IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) |
210 | IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) | 209 | IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) |
211 | IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) | 210 | IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) |
@@ -280,10 +279,6 @@ IF_SETKEYCODES(APPLET(setkeycodes, BB_DIR_USR_BIN, BB_SUID_DROP)) | |||
280 | IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 279 | IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
281 | IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 280 | IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
282 | IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) | 281 | IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) |
283 | IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) | ||
284 | IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) | ||
285 | IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) | ||
286 | IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) | ||
287 | IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) | 282 | IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) |
288 | IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) | 283 | IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) |
289 | /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells: */ | 284 | /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells: */ |
diff --git a/include/libbb.h b/include/libbb.h index b2e4299dd..bf356d727 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1737,6 +1737,7 @@ typedef struct sha512_ctx_t { | |||
1737 | typedef struct sha3_ctx_t { | 1737 | typedef struct sha3_ctx_t { |
1738 | uint64_t state[25]; | 1738 | uint64_t state[25]; |
1739 | unsigned bytes_queued; | 1739 | unsigned bytes_queued; |
1740 | unsigned input_block_bytes; | ||
1740 | } sha3_ctx_t; | 1741 | } sha3_ctx_t; |
1741 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1742 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
1742 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1743 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index d08c6b2f7..7e7d8da2f 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -941,10 +941,6 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
941 | # define OPTIMIZE_SHA3_FOR_32 1 | 941 | # define OPTIMIZE_SHA3_FOR_32 1 |
942 | #endif | 942 | #endif |
943 | 943 | ||
944 | enum { | ||
945 | SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */ | ||
946 | }; | ||
947 | |||
948 | #if OPTIMIZE_SHA3_FOR_32 | 944 | #if OPTIMIZE_SHA3_FOR_32 |
949 | /* This splits every 64-bit word into a pair of 32-bit words, | 945 | /* This splits every 64-bit word into a pair of 32-bit words, |
950 | * even bits go into first word, odd bits go to second one. | 946 | * even bits go into first word, odd bits go to second one. |
@@ -1352,6 +1348,8 @@ static void sha3_process_block72(uint64_t *state) | |||
1352 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) | 1348 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) |
1353 | { | 1349 | { |
1354 | memset(ctx, 0, sizeof(*ctx)); | 1350 | memset(ctx, 0, sizeof(*ctx)); |
1351 | /* SHA3-512, user can override */ | ||
1352 | ctx->input_block_bytes = (1600 - 512*2) / 8; /* 72 bytes */ | ||
1355 | } | 1353 | } |
1356 | 1354 | ||
1357 | void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | 1355 | void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) |
@@ -1361,7 +1359,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1361 | unsigned bufpos = ctx->bytes_queued; | 1359 | unsigned bufpos = ctx->bytes_queued; |
1362 | 1360 | ||
1363 | while (1) { | 1361 | while (1) { |
1364 | unsigned remaining = SHA3_IBLK_BYTES - bufpos; | 1362 | unsigned remaining = ctx->input_block_bytes - bufpos; |
1365 | if (remaining > len) | 1363 | if (remaining > len) |
1366 | remaining = len; | 1364 | remaining = len; |
1367 | len -= remaining; | 1365 | len -= remaining; |
@@ -1373,38 +1371,41 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1373 | remaining--; | 1371 | remaining--; |
1374 | } | 1372 | } |
1375 | /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ | 1373 | /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ |
1376 | bufpos -= SHA3_IBLK_BYTES; | 1374 | bufpos -= ctx->input_block_bytes; |
1377 | if (bufpos != 0) | 1375 | if (bufpos != 0) |
1378 | break; | 1376 | break; |
1379 | /* Buffer is filled up, process it */ | 1377 | /* Buffer is filled up, process it */ |
1380 | sha3_process_block72(ctx->state); | 1378 | sha3_process_block72(ctx->state); |
1381 | /*bufpos = 0; - already is */ | 1379 | /*bufpos = 0; - already is */ |
1382 | } | 1380 | } |
1383 | ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES; | 1381 | ctx->bytes_queued = bufpos + ctx->input_block_bytes; |
1384 | #else | 1382 | #else |
1385 | /* +50 bytes code size, but a bit faster because of long-sized XORs */ | 1383 | /* +50 bytes code size, but a bit faster because of long-sized XORs */ |
1386 | const uint8_t *data = buffer; | 1384 | const uint8_t *data = buffer; |
1387 | unsigned bufpos = ctx->bytes_queued; | 1385 | unsigned bufpos = ctx->bytes_queued; |
1386 | unsigned iblk_bytes = ctx->input_block_bytes; | ||
1388 | 1387 | ||
1389 | /* If already data in queue, continue queuing first */ | 1388 | /* If already data in queue, continue queuing first */ |
1390 | while (len != 0 && bufpos != 0) { | 1389 | if (bufpos != 0) { |
1391 | uint8_t *buf = (uint8_t*)ctx->state; | 1390 | while (len != 0) { |
1392 | buf[bufpos] ^= *data++; | 1391 | uint8_t *buf = (uint8_t*)ctx->state; |
1393 | len--; | 1392 | buf[bufpos] ^= *data++; |
1394 | bufpos++; | 1393 | len--; |
1395 | if (bufpos == SHA3_IBLK_BYTES) { | 1394 | bufpos++; |
1396 | bufpos = 0; | 1395 | if (bufpos == iblk_bytes) { |
1397 | goto do_block; | 1396 | bufpos = 0; |
1397 | goto do_block; | ||
1398 | } | ||
1398 | } | 1399 | } |
1399 | } | 1400 | } |
1400 | 1401 | ||
1401 | /* Absorb complete blocks */ | 1402 | /* Absorb complete blocks */ |
1402 | while (len >= SHA3_IBLK_BYTES) { | 1403 | while (len >= iblk_bytes) { |
1403 | /* XOR data onto beginning of state[]. | 1404 | /* XOR data onto beginning of state[]. |
1404 | * We try to be efficient - operate one word at a time, not byte. | 1405 | * We try to be efficient - operate one word at a time, not byte. |
1405 | * Careful wrt unaligned access: can't just use "*(long*)data"! | 1406 | * Careful wrt unaligned access: can't just use "*(long*)data"! |
1406 | */ | 1407 | */ |
1407 | unsigned count = SHA3_IBLK_BYTES / sizeof(long); | 1408 | unsigned count = iblk_bytes / sizeof(long); |
1408 | long *buf = (long*)ctx->state; | 1409 | long *buf = (long*)ctx->state; |
1409 | do { | 1410 | do { |
1410 | long v; | 1411 | long v; |
@@ -1412,7 +1413,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1412 | *buf++ ^= v; | 1413 | *buf++ ^= v; |
1413 | data += sizeof(long); | 1414 | data += sizeof(long); |
1414 | } while (--count); | 1415 | } while (--count); |
1415 | len -= SHA3_IBLK_BYTES; | 1416 | len -= iblk_bytes; |
1416 | do_block: | 1417 | do_block: |
1417 | sha3_process_block72(ctx->state); | 1418 | sha3_process_block72(ctx->state); |
1418 | } | 1419 | } |
@@ -1433,8 +1434,22 @@ void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | |||
1433 | { | 1434 | { |
1434 | /* Padding */ | 1435 | /* Padding */ |
1435 | uint8_t *buf = (uint8_t*)ctx->state; | 1436 | uint8_t *buf = (uint8_t*)ctx->state; |
1436 | buf[ctx->bytes_queued] ^= 1; | 1437 | /* |
1437 | buf[SHA3_IBLK_BYTES - 1] ^= 0x80; | 1438 | * Keccak block padding is: add 1 bit after last bit of input, |
1439 | * then add zero bits until the end of block, and add the last 1 bit | ||
1440 | * (the last bit in the block) - the "10*1" pattern. | ||
1441 | * SHA3 standard appends additional two bits, 01, before that padding: | ||
1442 | * | ||
1443 | * SHA3-224(M) = KECCAK[448](M||01, 224) | ||
1444 | * SHA3-256(M) = KECCAK[512](M||01, 256) | ||
1445 | * SHA3-384(M) = KECCAK[768](M||01, 384) | ||
1446 | * SHA3-512(M) = KECCAK[1024](M||01, 512) | ||
1447 | * (M is the input, || is bit concatenation) | ||
1448 | * | ||
1449 | * The 6 below contains 01 "SHA3" bits and the first 1 "Keccak" bit: | ||
1450 | */ | ||
1451 | buf[ctx->bytes_queued] ^= 6; /* bit pattern 00000110 */ | ||
1452 | buf[ctx->input_block_bytes - 1] ^= 0x80; | ||
1438 | 1453 | ||
1439 | sha3_process_block72(ctx->state); | 1454 | sha3_process_block72(ctx->state); |
1440 | 1455 | ||
diff --git a/testsuite/sha3sum.tests b/testsuite/sha3sum.tests index 82fada633..2cd8e3bf2 100755 --- a/testsuite/sha3sum.tests +++ b/testsuite/sha3sum.tests | |||
@@ -1,3 +1,3 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | . ./md5sum.tests sha3sum c29d77bc548fa2b20a04c861400a5360879c52156e2a54a3415b99a9a3123e1d5f36714a24eca8c1f05a8e2d8ba859c930d41141f64a255c6794436fc99c486a | 3 | . ./md5sum.tests sha3sum 11659f09370139f8ef384f4a6260947fafa6e4fcd87a1ef3f35410e9 |