diff options
| -rw-r--r-- | coreutils/Config.src | 12 | ||||
| -rw-r--r-- | coreutils/Kbuild.src | 1 | ||||
| -rw-r--r-- | coreutils/md5_sha1_sum.c | 17 | ||||
| -rw-r--r-- | include/applets.src.h | 1 | ||||
| -rw-r--r-- | include/libbb.h | 7 | ||||
| -rw-r--r-- | include/platform.h | 5 | ||||
| -rw-r--r-- | libbb/hash_md5_sha.c | 194 | ||||
| -rwxr-xr-x | testsuite/sha3sum.tests | 3 |
8 files changed, 236 insertions, 4 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src index a28449b11..0c44c4b51 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
| @@ -514,6 +514,12 @@ config SHA512SUM | |||
| 514 | help | 514 | help |
| 515 | Compute and check SHA512 message digest | 515 | Compute and check SHA512 message digest |
| 516 | 516 | ||
| 517 | config SHA3SUM | ||
| 518 | bool "sha3sum" | ||
| 519 | default y | ||
| 520 | help | ||
| 521 | Compute and check SHA3 (512-bit) message digest | ||
| 522 | |||
| 517 | config SLEEP | 523 | config SLEEP |
| 518 | bool "sleep" | 524 | bool "sleep" |
| 519 | default y | 525 | default y |
| @@ -766,13 +772,13 @@ config FEATURE_HUMAN_READABLE | |||
| 766 | help | 772 | help |
| 767 | Allow df, du, and ls to have human readable output. | 773 | Allow df, du, and ls to have human readable output. |
| 768 | 774 | ||
| 769 | comment "Common options for md5sum, sha1sum, sha256sum, sha512sum" | 775 | comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" |
| 770 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM | 776 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM |
| 771 | 777 | ||
| 772 | config FEATURE_MD5_SHA1_SUM_CHECK | 778 | config FEATURE_MD5_SHA1_SUM_CHECK |
| 773 | bool "Enable -c, -s and -w options" | 779 | bool "Enable -c, -s and -w options" |
| 774 | default y | 780 | default y |
| 775 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM | 781 | depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM |
| 776 | help | 782 | help |
| 777 | Enabling the -c options allows files to be checked | 783 | Enabling the -c options allows files to be checked |
| 778 | against pre-calculated hash values. | 784 | against pre-calculated hash values. |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index d6453f014..b715b9c47 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
| @@ -62,6 +62,7 @@ lib-$(CONFIG_SEQ) += seq.o | |||
| 62 | lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o | 62 | lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o |
| 63 | lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o | 63 | lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o |
| 64 | lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o | 64 | lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o |
| 65 | lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o | ||
| 65 | lib-$(CONFIG_SLEEP) += sleep.o | 66 | lib-$(CONFIG_SLEEP) += sleep.o |
| 66 | lib-$(CONFIG_SPLIT) += split.o | 67 | lib-$(CONFIG_SPLIT) += split.o |
| 67 | lib-$(CONFIG_SORT) += sort.o | 68 | lib-$(CONFIG_SORT) += sort.o |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 59b520fce..92a4d4462 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
| @@ -55,6 +55,16 @@ | |||
| 55 | //usage: "\n -s Don't output anything, status code shows success" | 55 | //usage: "\n -s Don't output anything, status code shows success" |
| 56 | //usage: "\n -w Warn about improperly formatted checksum lines" | 56 | //usage: "\n -w Warn about improperly formatted checksum lines" |
| 57 | //usage: ) | 57 | //usage: ) |
| 58 | //usage: | ||
| 59 | //usage:#define sha3sum_trivial_usage | ||
| 60 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." | ||
| 61 | //usage:#define sha3sum_full_usage "\n\n" | ||
| 62 | //usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums" | ||
| 63 | //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" | ||
| 64 | //usage: "\n -c Check sums against list in FILEs" | ||
| 65 | //usage: "\n -s Don't output anything, status code shows success" | ||
| 66 | //usage: "\n -w Warn about improperly formatted checksum lines" | ||
| 67 | //usage: ) | ||
| 58 | 68 | ||
| 59 | #include "libbb.h" | 69 | #include "libbb.h" |
| 60 | 70 | ||
| @@ -65,6 +75,7 @@ enum { | |||
| 65 | HASH_MD5 = 's', /* "md5>s<um" */ | 75 | HASH_MD5 = 's', /* "md5>s<um" */ |
| 66 | HASH_SHA1 = '1', | 76 | HASH_SHA1 = '1', |
| 67 | HASH_SHA256 = '2', | 77 | HASH_SHA256 = '2', |
| 78 | HASH_SHA3 = '3', | ||
| 68 | HASH_SHA512 = '5', | 79 | HASH_SHA512 = '5', |
| 69 | }; | 80 | }; |
| 70 | 81 | ||
| @@ -86,6 +97,7 @@ static uint8_t *hash_file(const char *filename) | |||
| 86 | { | 97 | { |
| 87 | int src_fd, hash_len, count; | 98 | int src_fd, hash_len, count; |
| 88 | union _ctx_ { | 99 | union _ctx_ { |
| 100 | sha3_ctx_t sha3; | ||
| 89 | sha512_ctx_t sha512; | 101 | sha512_ctx_t sha512; |
| 90 | sha256_ctx_t sha256; | 102 | sha256_ctx_t sha256; |
| 91 | sha1_ctx_t sha1; | 103 | sha1_ctx_t sha1; |
| @@ -124,6 +136,11 @@ static uint8_t *hash_file(const char *filename) | |||
| 124 | update = (void*)sha512_hash; | 136 | update = (void*)sha512_hash; |
| 125 | final = (void*)sha512_end; | 137 | final = (void*)sha512_end; |
| 126 | hash_len = 64; | 138 | hash_len = 64; |
| 139 | } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { | ||
| 140 | sha3_begin(&context.sha3); | ||
| 141 | update = (void*)sha3_hash; | ||
| 142 | final = (void*)sha3_end; | ||
| 143 | hash_len = 64; | ||
| 127 | } else { | 144 | } else { |
| 128 | xfunc_die(); /* can't reach this */ | 145 | xfunc_die(); /* can't reach this */ |
| 129 | } | 146 | } |
diff --git a/include/applets.src.h b/include/applets.src.h index 597b1c9a6..29ab16706 100644 --- a/include/applets.src.h +++ b/include/applets.src.h | |||
| @@ -328,6 +328,7 @@ IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) | |||
| 328 | IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) | 328 | IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) |
| 329 | IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) | 329 | IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) |
| 330 | IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) | 330 | IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) |
| 331 | IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) | ||
| 331 | IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) | 332 | IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) |
| 332 | IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) | 333 | IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) |
| 333 | IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) | 334 | IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) |
diff --git a/include/libbb.h b/include/libbb.h index 2059567e0..6ac7d2cab 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -1636,6 +1636,10 @@ typedef struct sha512_ctx_t { | |||
| 1636 | uint64_t hash[8]; | 1636 | uint64_t hash[8]; |
| 1637 | uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ | 1637 | uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ |
| 1638 | } sha512_ctx_t; | 1638 | } sha512_ctx_t; |
| 1639 | typedef struct sha3_ctx_t { | ||
| 1640 | uint64_t state[25]; | ||
| 1641 | unsigned bytes_queued; | ||
| 1642 | } sha3_ctx_t; | ||
| 1639 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1643 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
| 1640 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; | 1644 | void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; |
| 1641 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1645 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| @@ -1648,6 +1652,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | |||
| 1648 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1652 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
| 1649 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1653 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| 1650 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1654 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| 1655 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; | ||
| 1656 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | ||
| 1657 | void sha3_end(sha3_ctx_t *ctx, uint8_t *resbuf) FAST_FUNC; | ||
| 1651 | 1658 | ||
| 1652 | extern uint32_t *global_crc32_table; | 1659 | extern uint32_t *global_crc32_table; |
| 1653 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 1660 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
diff --git a/include/platform.h b/include/platform.h index 4025561c6..128230658 100644 --- a/include/platform.h +++ b/include/platform.h | |||
| @@ -205,6 +205,7 @@ | |||
| 205 | 205 | ||
| 206 | #include <stdint.h> | 206 | #include <stdint.h> |
| 207 | typedef int bb__aliased_int FIX_ALIASING; | 207 | typedef int bb__aliased_int FIX_ALIASING; |
| 208 | typedef long bb__aliased_long FIX_ALIASING; | ||
| 208 | typedef uint16_t bb__aliased_uint16_t FIX_ALIASING; | 209 | typedef uint16_t bb__aliased_uint16_t FIX_ALIASING; |
| 209 | typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; | 210 | typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; |
| 210 | 211 | ||
| @@ -212,7 +213,8 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; | |||
| 212 | * a lvalue. This makes it more likely to not swap them by mistake | 213 | * a lvalue. This makes it more likely to not swap them by mistake |
| 213 | */ | 214 | */ |
| 214 | #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) | 215 | #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) |
| 215 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) | 216 | # define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) |
| 217 | # define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp)) | ||
| 216 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) | 218 | # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) |
| 217 | # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) | 219 | # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) |
| 218 | # define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v)) | 220 | # define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v)) |
| @@ -221,6 +223,7 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; | |||
| 221 | #else | 223 | #else |
| 222 | /* performs reasonably well (gcc usually inlines memcpy here) */ | 224 | /* performs reasonably well (gcc usually inlines memcpy here) */ |
| 223 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) | 225 | # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) |
| 226 | # define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) | ||
| 224 | # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) | 227 | # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) |
| 225 | # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) | 228 | # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) |
| 226 | # define move_to_unaligned16(u16p, v) do { \ | 229 | # define move_to_unaligned16(u16p, v) do { \ |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index a313c2a65..06a2400b5 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
| @@ -31,6 +31,11 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n) | |||
| 31 | return (x >> n) | (x << (64 - n)); | 31 | return (x >> n) | (x << (64 - n)); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | /* rotl64 only used for sha3 currently */ | ||
| 35 | static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) | ||
| 36 | { | ||
| 37 | return (x << n) | (x >> (64 - n)); | ||
| 38 | } | ||
| 34 | 39 | ||
| 35 | /* Feed data through a temporary buffer. | 40 | /* Feed data through a temporary buffer. |
| 36 | * The internal buffer remembers previous data until it has 64 | 41 | * The internal buffer remembers previous data until it has 64 |
| @@ -896,3 +901,192 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
| 896 | } | 901 | } |
| 897 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 902 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); |
| 898 | } | 903 | } |
| 904 | |||
| 905 | |||
| 906 | /* | ||
| 907 | * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, | ||
| 908 | * Michael Peeters and Gilles Van Assche. For more information, feedback or | ||
| 909 | * questions, please refer to our website: http://keccak.noekeon.org/ | ||
| 910 | * | ||
| 911 | * Implementation by Ronny Van Keer, | ||
| 912 | * hereby denoted as "the implementer". | ||
| 913 | * | ||
| 914 | * To the extent possible under law, the implementer has waived all copyright | ||
| 915 | * and related or neighboring rights to the source code in this file. | ||
| 916 | * http://creativecommons.org/publicdomain/zero/1.0/ | ||
| 917 | * | ||
| 918 | * Busybox modifications (C) Lauri Kasanen, under the GPLv2. | ||
| 919 | */ | ||
| 920 | |||
| 921 | enum { | ||
| 922 | cKeccakR_SizeInBytes = 576 / 8, | ||
| 923 | cKeccakNumberOfRounds = 24, | ||
| 924 | }; | ||
| 925 | |||
| 926 | static const uint64_t KeccakF_RoundConstants[cKeccakNumberOfRounds] = { | ||
| 927 | 0x0000000000000001ULL, | ||
| 928 | 0x0000000000008082ULL, | ||
| 929 | 0x800000000000808aULL, | ||
| 930 | 0x8000000080008000ULL, | ||
| 931 | 0x000000000000808bULL, | ||
| 932 | 0x0000000080000001ULL, | ||
| 933 | 0x8000000080008081ULL, | ||
| 934 | 0x8000000000008009ULL, | ||
| 935 | 0x000000000000008aULL, | ||
| 936 | 0x0000000000000088ULL, | ||
| 937 | 0x0000000080008009ULL, | ||
| 938 | 0x000000008000000aULL, | ||
| 939 | 0x000000008000808bULL, | ||
| 940 | 0x800000000000008bULL, | ||
| 941 | 0x8000000000008089ULL, | ||
| 942 | 0x8000000000008003ULL, | ||
| 943 | 0x8000000000008002ULL, | ||
| 944 | 0x8000000000000080ULL, | ||
| 945 | 0x000000000000800aULL, | ||
| 946 | 0x800000008000000aULL, | ||
| 947 | 0x8000000080008081ULL, | ||
| 948 | 0x8000000000008080ULL, | ||
| 949 | 0x0000000080000001ULL, | ||
| 950 | 0x8000000080008008ULL | ||
| 951 | }; | ||
| 952 | |||
| 953 | static const uint8_t KeccakF_RotationConstants[25] = { | ||
| 954 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, | ||
| 955 | 18, 39, 61, 20, 44 | ||
| 956 | }; | ||
| 957 | |||
| 958 | static const uint8_t KeccakF_PiLane[25] = { | ||
| 959 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, | ||
| 960 | 14, 22, 9, 6, 1 | ||
| 961 | }; | ||
| 962 | |||
| 963 | static const uint8_t KeccakF_Mod5[10] = { | ||
| 964 | 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 | ||
| 965 | }; | ||
| 966 | |||
| 967 | static void KeccakF(uint64_t *state) | ||
| 968 | { | ||
| 969 | uint8_t x, y; | ||
| 970 | uint64_t temp; | ||
| 971 | uint64_t BC[5]; | ||
| 972 | int round; | ||
| 973 | |||
| 974 | if (BB_BIG_ENDIAN) { | ||
| 975 | for (x = 0; x < 25; x++) { | ||
| 976 | state[x] = SWAP_LE64(state[x]); | ||
| 977 | } | ||
| 978 | } | ||
| 979 | |||
| 980 | for (round = 0; round < cKeccakNumberOfRounds; ++round) { | ||
| 981 | /* Theta */ | ||
| 982 | for (x = 0; x < 5; ++x) { | ||
| 983 | BC[x] = state[x] ^ state[5 + x] ^ state[10 + x] ^ | ||
| 984 | state[15 + x] ^ state[20 + x]; | ||
| 985 | } | ||
| 986 | for (x = 0; x < 5; ++x) { | ||
| 987 | temp = BC[KeccakF_Mod5[x + 4]] ^ | ||
| 988 | rotl64(BC[KeccakF_Mod5[x + 1]], 1); | ||
| 989 | |||
| 990 | for (y = 0; y <= 20; y += 5) { | ||
| 991 | state[y + x] ^= temp; | ||
| 992 | } | ||
| 993 | } | ||
| 994 | |||
| 995 | /* Rho Pi */ | ||
| 996 | temp = state[1]; | ||
| 997 | for (x = 0; x < 24; ++x) { | ||
| 998 | BC[0] = state[KeccakF_PiLane[x]]; | ||
| 999 | state[KeccakF_PiLane[x]] = | ||
| 1000 | rotl64(temp, KeccakF_RotationConstants[x]); | ||
| 1001 | temp = BC[0]; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | /* Chi */ | ||
| 1005 | for (y = 0; y < 25; y += 5) { | ||
| 1006 | BC[0] = state[y + 0]; | ||
| 1007 | BC[1] = state[y + 1]; | ||
| 1008 | BC[2] = state[y + 2]; | ||
| 1009 | BC[3] = state[y + 3]; | ||
| 1010 | BC[4] = state[y + 4]; | ||
| 1011 | for (x = 0; x < 5; ++x) { | ||
| 1012 | state[y + x] = | ||
| 1013 | BC[x] ^ ((~BC[KeccakF_Mod5[x + 1]]) & | ||
| 1014 | BC[KeccakF_Mod5[x + 2]]); | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | /* Iota */ | ||
| 1019 | state[0] ^= KeccakF_RoundConstants[round]; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | if (BB_BIG_ENDIAN) { | ||
| 1023 | for (x = 0; x < 25; x++) { | ||
| 1024 | state[x] = SWAP_LE64(state[x]); | ||
| 1025 | } | ||
| 1026 | } | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) | ||
| 1030 | { | ||
| 1031 | memset(ctx, 0, sizeof(*ctx)); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buf, size_t bytes) | ||
| 1035 | { | ||
| 1036 | const uint8_t *data = buf; | ||
| 1037 | |||
| 1038 | /* If already data in queue, continue queuing first */ | ||
| 1039 | while (bytes != 0 && ctx->bytes_queued != 0) { | ||
| 1040 | uint8_t *buffer = (uint8_t*)ctx->state; | ||
| 1041 | buffer[ctx->bytes_queued] ^= *data++; | ||
| 1042 | bytes--; | ||
| 1043 | ctx->bytes_queued++; | ||
| 1044 | if (ctx->bytes_queued == cKeccakR_SizeInBytes) { | ||
| 1045 | KeccakF(ctx->state); | ||
| 1046 | ctx->bytes_queued = 0; | ||
| 1047 | } | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | /* Absorb complete blocks */ | ||
| 1051 | while (bytes >= cKeccakR_SizeInBytes) { | ||
| 1052 | /* XOR data onto beginning of state[]. | ||
| 1053 | * We try to be efficient - operate on word at a time, not byte. | ||
| 1054 | * Yet safe wrt unaligned access: can't just use "*(long*)data"... | ||
| 1055 | */ | ||
| 1056 | unsigned count = cKeccakR_SizeInBytes / sizeof(long); | ||
| 1057 | long *buffer = (long*)ctx->state; | ||
| 1058 | do { | ||
| 1059 | long v; | ||
| 1060 | move_from_unaligned_long(v, (long*)data); | ||
| 1061 | *buffer++ ^= v; | ||
| 1062 | data += sizeof(long); | ||
| 1063 | } while (--count); | ||
| 1064 | |||
| 1065 | KeccakF(ctx->state); | ||
| 1066 | bytes -= cKeccakR_SizeInBytes; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | /* Queue remaining data bytes */ | ||
| 1070 | while (bytes != 0) { | ||
| 1071 | uint8_t *buffer = (uint8_t*)ctx->state; | ||
| 1072 | buffer[ctx->bytes_queued] ^= *data++; | ||
| 1073 | ctx->bytes_queued++; | ||
| 1074 | bytes--; | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | void FAST_FUNC sha3_end(sha3_ctx_t *ctx, uint8_t *hashval) | ||
| 1079 | { | ||
| 1080 | /* Padding */ | ||
| 1081 | uint8_t *buffer = (uint8_t*)ctx->state; | ||
| 1082 | /* 0 is the number of bits in last, incomplete byte | ||
| 1083 | * (that is, zero: we never have incomplete bytes): | ||
| 1084 | */ | ||
| 1085 | buffer[ctx->bytes_queued] ^= 1 << 0; | ||
| 1086 | buffer[cKeccakR_SizeInBytes - 1] ^= 0x80; | ||
| 1087 | |||
| 1088 | KeccakF(ctx->state); | ||
| 1089 | |||
| 1090 | /* Output */ | ||
| 1091 | memcpy(hashval, ctx->state, 64); | ||
| 1092 | } | ||
diff --git a/testsuite/sha3sum.tests b/testsuite/sha3sum.tests new file mode 100755 index 000000000..82fada633 --- /dev/null +++ b/testsuite/sha3sum.tests | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | . ./md5sum.tests sha3sum c29d77bc548fa2b20a04c861400a5360879c52156e2a54a3415b99a9a3123e1d5f36714a24eca8c1f05a8e2d8ba859c930d41141f64a255c6794436fc99c486a | ||
