aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauri Kasanen <curaga@operamail.com>2013-01-14 05:20:50 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2013-01-14 05:20:50 +0100
commitb8173b603f57dcf918a67f1ec00763ab5f4e1cf8 (patch)
tree726549290ba408cf68561c4c1c2d591a80ded319
parentb7841cf7b919b16d1bd4619154bf7cb4c22b4ccd (diff)
downloadbusybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.tar.gz
busybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.tar.bz2
busybox-w32-b8173b603f57dcf918a67f1ec00763ab5f4e1cf8.zip
sha3sum: new applet
function old new delta KeccakF - 496 +496 KeccakF_RoundConstants - 192 +192 sha3_hash - 171 +171 sha3_end - 40 +40 hash_file 274 299 +25 KeccakF_RotationConstants - 25 +25 KeccakF_PiLane - 25 +25 packed_usage 29213 29232 +19 sha3_begin - 18 +18 KeccakF_Mod5 - 10 +10 applet_names 2445 2453 +8 applet_main 1420 1424 +4 applet_nameofs 710 712 +2 ------------------------------------------------------------------------------ (add/remove: 8/0 grow/shrink: 9/7 up/down: 1049/-54) Total: ~995 bytes Signed-off-by: Lauri Kasanen <curaga@operamail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/Config.src12
-rw-r--r--coreutils/Kbuild.src1
-rw-r--r--coreutils/md5_sha1_sum.c17
-rw-r--r--include/applets.src.h1
-rw-r--r--include/libbb.h7
-rw-r--r--include/platform.h5
-rw-r--r--libbb/hash_md5_sha.c194
-rwxr-xr-xtestsuite/sha3sum.tests3
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
517config SHA3SUM
518 bool "sha3sum"
519 default y
520 help
521 Compute and check SHA3 (512-bit) message digest
522
517config SLEEP 523config 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
769comment "Common options for md5sum, sha1sum, sha256sum, sha512sum" 775comment "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
772config FEATURE_MD5_SHA1_SUM_CHECK 778config 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
62lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o 62lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o
63lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o 63lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
64lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o 64lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
65lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o
65lib-$(CONFIG_SLEEP) += sleep.o 66lib-$(CONFIG_SLEEP) += sleep.o
66lib-$(CONFIG_SPLIT) += split.o 67lib-$(CONFIG_SPLIT) += split.o
67lib-$(CONFIG_SORT) += sort.o 68lib-$(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))
328IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) 328IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP))
329IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) 329IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid))
330IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) 330IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum))
331IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum))
331IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) 332IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum))
332IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) 333IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum))
333IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) 334IF_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;
1639typedef struct sha3_ctx_t {
1640 uint64_t state[25];
1641 unsigned bytes_queued;
1642} sha3_ctx_t;
1639void md5_begin(md5_ctx_t *ctx) FAST_FUNC; 1643void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1640void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; 1644void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
1641void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; 1645void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
@@ -1648,6 +1652,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1648void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 1652void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1649void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 1653void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1650void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; 1654void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1655void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
1656void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1657void sha3_end(sha3_ctx_t *ctx, uint8_t *resbuf) FAST_FUNC;
1651 1658
1652extern uint32_t *global_crc32_table; 1659extern uint32_t *global_crc32_table;
1653uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; 1660uint32_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>
207typedef int bb__aliased_int FIX_ALIASING; 207typedef int bb__aliased_int FIX_ALIASING;
208typedef long bb__aliased_long FIX_ALIASING;
208typedef uint16_t bb__aliased_uint16_t FIX_ALIASING; 209typedef uint16_t bb__aliased_uint16_t FIX_ALIASING;
209typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; 210typedef 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 */
35static 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
921enum {
922 cKeccakR_SizeInBytes = 576 / 8,
923 cKeccakNumberOfRounds = 24,
924};
925
926static 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
953static 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
958static 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
963static const uint8_t KeccakF_Mod5[10] = {
964 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
965};
966
967static 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
1029void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
1030{
1031 memset(ctx, 0, sizeof(*ctx));
1032}
1033
1034void 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
1078void 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