aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-08-29 14:05:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-08-29 14:05:25 +0200
commit71a090f1871f165ebf3c31f733b36aafca71a6b4 (patch)
tree4f0b38ba12a6e5b80aa829574f999ae1efd9f17a
parentd3d7f085ebf2898b62d4bb75566122c65be96454 (diff)
downloadbusybox-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.src43
-rw-r--r--coreutils/Kbuild.src5
-rw-r--r--coreutils/md5_sha1_sum.c122
-rw-r--r--include/applets.src.h5
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/hash_md5_sha.c55
-rwxr-xr-xtestsuite/sha3sum.tests2
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
331config MD5SUM
332 bool "md5sum"
333 default y
334 help
335 md5sum is used to print or check MD5 checksums.
336
337config MKDIR 331config 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
461config SHA1SUM
462 bool "sha1sum"
463 default y
464 help
465 Compute and check SHA1 message digest
466
467config SHA256SUM
468 bool "sha256sum"
469 default y
470 help
471 Compute and check SHA256 message digest
472
473config SHA512SUM
474 bool "sha512sum"
475 default y
476 help
477 Compute and check SHA512 message digest
478
479config SHA3SUM
480 bool "sha3sum"
481 default y
482 help
483 Compute and check SHA3 (512-bit) message digest
484
485config SLEEP 455config 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
734comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
735 depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
736
737config 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
747endmenu 704endmenu
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
41lib-$(CONFIG_LOGNAME) += logname.o 41lib-$(CONFIG_LOGNAME) += logname.o
42lib-$(CONFIG_LS) += ls.o 42lib-$(CONFIG_LS) += ls.o
43lib-$(CONFIG_FTPD) += ls.o 43lib-$(CONFIG_FTPD) += ls.o
44lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o
45lib-$(CONFIG_MKDIR) += mkdir.o 44lib-$(CONFIG_MKDIR) += mkdir.o
46lib-$(CONFIG_MKFIFO) += mkfifo.o 45lib-$(CONFIG_MKFIFO) += mkfifo.o
47lib-$(CONFIG_MKNOD) += mknod.o 46lib-$(CONFIG_MKNOD) += mknod.o
@@ -58,10 +57,6 @@ lib-$(CONFIG_REALPATH) += realpath.o
58lib-$(CONFIG_RM) += rm.o 57lib-$(CONFIG_RM) += rm.o
59lib-$(CONFIG_RMDIR) += rmdir.o 58lib-$(CONFIG_RMDIR) += rmdir.o
60lib-$(CONFIG_SEQ) += seq.o 59lib-$(CONFIG_SEQ) += seq.o
61lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o
62lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
63lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
64lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o
65lib-$(CONFIG_SLEEP) += sleep.o 60lib-$(CONFIG_SLEEP) += sleep.o
66lib-$(CONFIG_SPLIT) += split.o 61lib-$(CONFIG_SPLIT) += split.o
67lib-$(CONFIG_SORT) += sort.o 62lib-$(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
100static 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)
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))
205IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) 205IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP))
206IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP)) 206IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP))
207IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) 207IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP))
208IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum))
209IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) 208IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP))
210IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) 209IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir))
211IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) 210IF_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))
280IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP)) 279IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP))
281IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) 280IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP))
282IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) 281IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP))
283IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum))
284IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum))
285IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum))
286IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum))
287IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) 282IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP))
288IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) 283IF_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 {
1737typedef struct sha3_ctx_t { 1737typedef 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;
1741void md5_begin(md5_ctx_t *ctx) FAST_FUNC; 1742void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1742void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 1743void 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
944enum {
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)
1352void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) 1348void 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
1357void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) 1355void 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