aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-02-07 14:25:54 +0000
committerRon Yorston <rmy@pobox.com>2013-02-07 14:25:54 +0000
commitb604585914e032b28bef3e337a978e56a9069cda (patch)
treeb2ee0a3fb38d10397c602d0fe215ea3bbbf334c0 /libbb
parent0eda07c7ff8cf1fc11bc1bda5383f884d7adf031 (diff)
parentba76b7a40b929878833731f76306b1c977cc8650 (diff)
downloadbusybox-w32-b604585914e032b28bef3e337a978e56a9069cda.tar.gz
busybox-w32-b604585914e032b28bef3e337a978e56a9069cda.tar.bz2
busybox-w32-b604585914e032b28bef3e337a978e56a9069cda.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Config.src10
-rw-r--r--libbb/appletlib.c20
-rw-r--r--libbb/hash_md5_sha.c294
-rw-r--r--libbb/inet_common.c4
-rw-r--r--libbb/loop.c6
-rw-r--r--libbb/procps.c2
-rw-r--r--libbb/selinux_common.c2
-rw-r--r--libbb/xatonum_template.c2
8 files changed, 312 insertions, 28 deletions
diff --git a/libbb/Config.src b/libbb/Config.src
index ee1b66a45..19021fed1 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -28,6 +28,16 @@ config MD5_SMALL
28 2 3.0 5088 28 2 3.0 5088
29 3 (smallest) 5.1 4912 29 3 (smallest) 5.1 4912
30 30
31config SHA3_SMALL
32 int "SHA3: Trade bytes for speed (0:fast, 1:slow)"
33 default 1
34 range 0 1
35 help
36 Trade binary size versus speed for the sha3sum algorithm.
37 SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate):
38 64-bit x86: +270 bytes of code, 45% faster
39 32-bit x86: +450 bytes of code, 75% faster
40
31config FEATURE_FAST_TOP 41config FEATURE_FAST_TOP
32 bool "Faster /proc scanning code (+100 bytes)" 42 bool "Faster /proc scanning code (+100 bytes)"
33 default y 43 default y
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 63ec010dd..fb06ab9a5 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -140,10 +140,9 @@ void FAST_FUNC bb_show_usage(void)
140} 140}
141 141
142#if NUM_APPLETS > 8 142#if NUM_APPLETS > 8
143/* NB: any char pointer will work as well, not necessarily applet_names */ 143static int applet_name_compare(const void *name, const void *idx)
144static int applet_name_compare(const void *name, const void *v)
145{ 144{
146 int i = (const char *)v - applet_names; 145 int i = (int)(ptrdiff_t)idx - 1;
147 return strcmp(name, APPLET_NAME(i)); 146 return strcmp(name, APPLET_NAME(i));
148} 147}
149#endif 148#endif
@@ -152,10 +151,12 @@ int FAST_FUNC find_applet_by_name(const char *name)
152#if NUM_APPLETS > 8 151#if NUM_APPLETS > 8
153 /* Do a binary search to find the applet entry given the name. */ 152 /* Do a binary search to find the applet entry given the name. */
154 const char *p; 153 const char *p;
155 p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare); 154 p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare);
156 if (!p) 155 /*
157 return -1; 156 * if (!p) return -1;
158 return p - applet_names; 157 * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :)
158 */
159 return (int)(ptrdiff_t)p - 1;
159#else 160#else
160 /* A version which does not pull in bsearch */ 161 /* A version which does not pull in bsearch */
161 int i = 0; 162 int i = 0;
@@ -749,8 +750,11 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv)
749 /* Special case. POSIX says "test --help" 750 /* Special case. POSIX says "test --help"
750 * should be no different from e.g. "test --foo". */ 751 * should be no different from e.g. "test --foo". */
751//TODO: just compare applet_no with APPLET_NO_test 752//TODO: just compare applet_no with APPLET_NO_test
752 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) 753 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) {
754 /* If you want "foo --help" to return 0: */
755 /*xfunc_error_retval = 0;*/
753 bb_show_usage(); 756 bb_show_usage();
757 }
754 } 758 }
755 if (ENABLE_FEATURE_SUID) 759 if (ENABLE_FEATURE_SUID)
756 check_suid(applet_no); 760 check_suid(applet_no);
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index a313c2a65..b4d955e5a 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
@@ -51,7 +56,7 @@ static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t l
51 len -= remaining; 56 len -= remaining;
52 buffer = (const char *)buffer + remaining; 57 buffer = (const char *)buffer + remaining;
53 bufpos += remaining; 58 bufpos += remaining;
54 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ 59 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
55 bufpos -= 64; 60 bufpos -= 64;
56 if (bufpos != 0) 61 if (bufpos != 0)
57 break; 62 break;
@@ -185,10 +190,9 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx)
185 int i; 190 int i;
186 uint32_t temp; 191 uint32_t temp;
187 192
188# if BB_BIG_ENDIAN 193 if (BB_BIG_ENDIAN)
189 for (i = 0; i < 16; i++) 194 for (i = 0; i < 16; i++)
190 words[i] = SWAP_LE32(words[i]); 195 words[i] = SWAP_LE32(words[i]);
191# endif
192 196
193# if MD5_SMALL == 3 197# if MD5_SMALL == 3
194 pc = C_array; 198 pc = C_array;
@@ -462,12 +466,13 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
462 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); 466 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN);
463 467
464 /* The MD5 result is in little endian byte order */ 468 /* The MD5 result is in little endian byte order */
465#if BB_BIG_ENDIAN 469 if (BB_BIG_ENDIAN) {
466 ctx->hash[0] = SWAP_LE32(ctx->hash[0]); 470 ctx->hash[0] = SWAP_LE32(ctx->hash[0]);
467 ctx->hash[1] = SWAP_LE32(ctx->hash[1]); 471 ctx->hash[1] = SWAP_LE32(ctx->hash[1]);
468 ctx->hash[2] = SWAP_LE32(ctx->hash[2]); 472 ctx->hash[2] = SWAP_LE32(ctx->hash[2]);
469 ctx->hash[3] = SWAP_LE32(ctx->hash[3]); 473 ctx->hash[3] = SWAP_LE32(ctx->hash[3]);
470#endif 474 }
475
471 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); 476 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4);
472} 477}
473 478
@@ -834,7 +839,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
834 len -= remaining; 839 len -= remaining;
835 buffer = (const char *)buffer + remaining; 840 buffer = (const char *)buffer + remaining;
836 bufpos += remaining; 841 bufpos += remaining;
837 /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ 842 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
838 bufpos -= 128; 843 bufpos -= 128;
839 if (bufpos != 0) 844 if (bufpos != 0)
840 break; 845 break;
@@ -896,3 +901,268 @@ 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#if CONFIG_SHA3_SMALL < 0
922# define SHA3_SMALL 0
923#elif CONFIG_SHA3_SMALL > 1
924# define SHA3_SMALL 1
925#else
926# define SHA3_SMALL CONFIG_SHA3_SMALL
927#endif
928
929enum {
930 SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */
931};
932
933/*
934 * In the crypto literature this function is usually called Keccak-f().
935 */
936static void sha3_process_block72(uint64_t *state)
937{
938 enum { NROUNDS = 24 };
939
940 /* Elements should be 64-bit, but top half is always zero or 0x80000000.
941 * We encode 63rd bits in a separate word below.
942 * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit.
943 * The speed penalty is lost in the noise.
944 */
945 static const uint16_t IOTA_CONST[NROUNDS] = {
946 0x0001,
947 0x8082,
948 0x808a,
949 0x8000,
950 0x808b,
951 0x0001,
952 0x8081,
953 0x8009,
954 0x008a,
955 0x0088,
956 0x8009,
957 0x000a,
958 0x808b,
959 0x008b,
960 0x8089,
961 0x8003,
962 0x8002,
963 0x0080,
964 0x800a,
965 0x000a,
966 0x8081,
967 0x8080,
968 0x0001,
969 0x8008,
970 };
971 /* bit for CONST[0] is in msb: 0011 0011 0000 0111 1101 1101 */
972 const uint32_t IOTA_CONST_bit63 = (uint32_t)(0x3307dd00);
973 /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */
974 const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00);
975
976 static const uint8_t ROT_CONST[24] = {
977 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
978 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44,
979 };
980 static const uint8_t PI_LANE[24] = {
981 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
982 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
983 };
984 /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/
985
986 unsigned x, y;
987 unsigned round;
988
989 if (BB_BIG_ENDIAN) {
990 for (x = 0; x < 25; x++) {
991 state[x] = SWAP_LE64(state[x]);
992 }
993 }
994
995 for (round = 0; round < NROUNDS; ++round) {
996 /* Theta */
997 {
998 uint64_t BC[10];
999 for (x = 0; x < 5; ++x) {
1000 BC[x + 5] = BC[x] = state[x]
1001 ^ state[x + 5] ^ state[x + 10]
1002 ^ state[x + 15] ^ state[x + 20];
1003 }
1004 /* Using 2x5 vector above eliminates the need to use
1005 * BC[MOD5[x+N]] trick below to fetch BC[(x+N) % 5],
1006 * and the code is a bit _smaller_.
1007 */
1008 for (x = 0; x < 5; ++x) {
1009 uint64_t temp = BC[x + 4] ^ rotl64(BC[x + 1], 1);
1010 state[x] ^= temp;
1011 state[x + 5] ^= temp;
1012 state[x + 10] ^= temp;
1013 state[x + 15] ^= temp;
1014 state[x + 20] ^= temp;
1015 }
1016 }
1017
1018 /* Rho Pi */
1019 if (SHA3_SMALL) {
1020 uint64_t t1 = state[1];
1021 for (x = 0; x < 24; ++x) {
1022 uint64_t t0 = state[PI_LANE[x]];
1023 state[PI_LANE[x]] = rotl64(t1, ROT_CONST[x]);
1024 t1 = t0;
1025 }
1026 } else {
1027 /* Especially large benefit for 32-bit arch (75% faster):
1028 * 64-bit rotations by non-constant usually are SLOW on those.
1029 * We resort to unrolling here.
1030 * This optimizes out PI_LANE[] and ROT_CONST[],
1031 * but generates 300-500 more bytes of code.
1032 */
1033 uint64_t t0;
1034 uint64_t t1 = state[1];
1035#define RhoPi_twice(x) \
1036 t0 = state[PI_LANE[x ]]; \
1037 state[PI_LANE[x ]] = rotl64(t1, ROT_CONST[x ]); \
1038 t1 = state[PI_LANE[x+1]]; \
1039 state[PI_LANE[x+1]] = rotl64(t0, ROT_CONST[x+1]);
1040 RhoPi_twice(0); RhoPi_twice(2);
1041 RhoPi_twice(4); RhoPi_twice(6);
1042 RhoPi_twice(8); RhoPi_twice(10);
1043 RhoPi_twice(12); RhoPi_twice(14);
1044 RhoPi_twice(16); RhoPi_twice(18);
1045 RhoPi_twice(20); RhoPi_twice(22);
1046#undef RhoPi_twice
1047 }
1048
1049 /* Chi */
1050 for (y = 0; y <= 20; y += 5) {
1051 uint64_t BC0, BC1, BC2, BC3, BC4;
1052 BC0 = state[y + 0];
1053 BC1 = state[y + 1];
1054 BC2 = state[y + 2];
1055 state[y + 0] = BC0 ^ ((~BC1) & BC2);
1056 BC3 = state[y + 3];
1057 state[y + 1] = BC1 ^ ((~BC2) & BC3);
1058 BC4 = state[y + 4];
1059 state[y + 2] = BC2 ^ ((~BC3) & BC4);
1060 state[y + 3] = BC3 ^ ((~BC4) & BC0);
1061 state[y + 4] = BC4 ^ ((~BC0) & BC1);
1062 }
1063
1064 /* Iota */
1065 state[0] ^= IOTA_CONST[round]
1066 | (uint32_t)((IOTA_CONST_bit31 << round) & 0x80000000)
1067 | (uint64_t)((IOTA_CONST_bit63 << round) & 0x80000000) << 32;
1068 }
1069
1070 if (BB_BIG_ENDIAN) {
1071 for (x = 0; x < 25; x++) {
1072 state[x] = SWAP_LE64(state[x]);
1073 }
1074 }
1075}
1076
1077void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
1078{
1079 memset(ctx, 0, sizeof(*ctx));
1080}
1081
1082void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
1083{
1084#if SHA3_SMALL
1085 const uint8_t *data = buffer;
1086 unsigned bufpos = ctx->bytes_queued;
1087
1088 while (1) {
1089 unsigned remaining = SHA3_IBLK_BYTES - bufpos;
1090 if (remaining > len)
1091 remaining = len;
1092 len -= remaining;
1093 /* XOR data into buffer */
1094 while (remaining != 0) {
1095 uint8_t *buf = (uint8_t*)ctx->state;
1096 buf[bufpos] ^= *data++;
1097 bufpos++;
1098 remaining--;
1099 }
1100 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
1101 bufpos -= SHA3_IBLK_BYTES;
1102 if (bufpos != 0)
1103 break;
1104 /* Buffer is filled up, process it */
1105 sha3_process_block72(ctx->state);
1106 /*bufpos = 0; - already is */
1107 }
1108 ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES;
1109#else
1110 /* +50 bytes code size, but a bit faster because of long-sized XORs */
1111 const uint8_t *data = buffer;
1112 unsigned bufpos = ctx->bytes_queued;
1113
1114 /* If already data in queue, continue queuing first */
1115 while (len != 0 && bufpos != 0) {
1116 uint8_t *buf = (uint8_t*)ctx->state;
1117 buf[bufpos] ^= *data++;
1118 len--;
1119 bufpos++;
1120 if (bufpos == SHA3_IBLK_BYTES) {
1121 bufpos = 0;
1122 goto do_block;
1123 }
1124 }
1125
1126 /* Absorb complete blocks */
1127 while (len >= SHA3_IBLK_BYTES) {
1128 /* XOR data onto beginning of state[].
1129 * We try to be efficient - operate one word at a time, not byte.
1130 * Careful wrt unaligned access: can't just use "*(long*)data"!
1131 */
1132 unsigned count = SHA3_IBLK_BYTES / sizeof(long);
1133 long *buf = (long*)ctx->state;
1134 do {
1135 long v;
1136 move_from_unaligned_long(v, (long*)data);
1137 *buf++ ^= v;
1138 data += sizeof(long);
1139 } while (--count);
1140 len -= SHA3_IBLK_BYTES;
1141 do_block:
1142 sha3_process_block72(ctx->state);
1143 }
1144
1145 /* Queue remaining data bytes */
1146 while (len != 0) {
1147 uint8_t *buf = (uint8_t*)ctx->state;
1148 buf[bufpos] ^= *data++;
1149 bufpos++;
1150 len--;
1151 }
1152
1153 ctx->bytes_queued = bufpos;
1154#endif
1155}
1156
1157void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1158{
1159 /* Padding */
1160 uint8_t *buf = (uint8_t*)ctx->state;
1161 buf[ctx->bytes_queued] ^= 1;
1162 buf[SHA3_IBLK_BYTES - 1] ^= 0x80;
1163
1164 sha3_process_block72(ctx->state);
1165
1166 /* Output */
1167 memcpy(resbuf, ctx->state, 64);
1168}
diff --git a/libbb/inet_common.c b/libbb/inet_common.c
index 7208db9ea..0f4fca1a2 100644
--- a/libbb/inet_common.c
+++ b/libbb/inet_common.c
@@ -97,7 +97,7 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne
97 if (s_in->sin_family != AF_INET) { 97 if (s_in->sin_family != AF_INET) {
98#ifdef DEBUG 98#ifdef DEBUG
99 bb_error_msg("rresolve: unsupported address family %d!", 99 bb_error_msg("rresolve: unsupported address family %d!",
100 s_in->sin_family); 100 s_in->sin_family);
101#endif 101#endif
102 errno = EAFNOSUPPORT; 102 errno = EAFNOSUPPORT;
103 return NULL; 103 return NULL;
@@ -195,7 +195,7 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
195 if (sin6->sin6_family != AF_INET6) { 195 if (sin6->sin6_family != AF_INET6) {
196#ifdef DEBUG 196#ifdef DEBUG
197 bb_error_msg("rresolve: unsupported address family %d!", 197 bb_error_msg("rresolve: unsupported address family %d!",
198 sin6->sin6_family); 198 sin6->sin6_family);
199#endif 199#endif
200 errno = EAFNOSUPPORT; 200 errno = EAFNOSUPPORT;
201 return NULL; 201 return NULL;
diff --git a/libbb/loop.c b/libbb/loop.c
index b3a520848..823fba079 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -150,9 +150,9 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
150 } 150 }
151 151
152 /* If this block device already set up right, re-use it. 152 /* If this block device already set up right, re-use it.
153 (Yes this is racy, but associating two loop devices with the same 153 * (Yes this is racy, but associating two loop devices with the same
154 file isn't pretty either. In general, mounting the same file twice 154 * file isn't pretty either. In general, mounting the same file twice
155 without using losetup manually is problematic.) 155 * without using losetup manually is problematic.)
156 */ 156 */
157 } else 157 } else
158 if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 158 if (strcmp(file, (char *)loopinfo.lo_file_name) != 0
diff --git a/libbb/procps.c b/libbb/procps.c
index c6977da51..e2f54d730 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -181,7 +181,7 @@ static char *skip_fields(char *str, int count)
181 181
182#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP 182#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
183int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, 183int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
184 void (*cb)(struct smaprec *, void *), void *data) 184 void (*cb)(struct smaprec *, void *), void *data)
185{ 185{
186 FILE *file; 186 FILE *file;
187 struct smaprec currec; 187 struct smaprec currec;
diff --git a/libbb/selinux_common.c b/libbb/selinux_common.c
index 62910e285..c2585557f 100644
--- a/libbb/selinux_common.c
+++ b/libbb/selinux_common.c
@@ -10,7 +10,7 @@
10#include <selinux/context.h> 10#include <selinux/context.h>
11 11
12context_t FAST_FUNC set_security_context_component(security_context_t cur_context, 12context_t FAST_FUNC set_security_context_component(security_context_t cur_context,
13 char *user, char *role, char *type, char *range) 13 char *user, char *role, char *type, char *range)
14{ 14{
15 context_t con = context_new(cur_context); 15 context_t con = context_new(cur_context);
16 if (!con) 16 if (!con)
diff --git a/libbb/xatonum_template.c b/libbb/xatonum_template.c
index 029f66202..e0471983c 100644
--- a/libbb/xatonum_template.c
+++ b/libbb/xatonum_template.c
@@ -59,7 +59,7 @@ unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
59 } 59 }
60 60
61 /* Note: trailing space is an error. 61 /* Note: trailing space is an error.
62 It would be easy enough to allow though if desired. */ 62 * It would be easy enough to allow though if desired. */
63 if (*e) 63 if (*e)
64 goto inval; 64 goto inval;
65 chk_range: 65 chk_range: