From 9fe98f701d40835db32baa12c94b661d40231ea4 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Thu, 16 Sep 2010 17:51:13 +0200
Subject: libbb: merge mail and uudecode's base64 decoders

function                                             old     new   delta
read_base64                                            -     378    +378
uudecode_main                                        306     315      +9
parse                                                953     958      +5
read_stduu                                           250     254      +4
base64_main                                          217     219      +2
read_base64                                          358       -    -358
decode_base64                                        371       -    -371
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 4/0 up/down: 398/-729)         Total: -331 bytes

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
---
 libbb/base64.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 libbb/base64.c

(limited to 'libbb')

diff --git a/libbb/base64.c b/libbb/base64.c
new file mode 100644
index 000000000..b9d47ae08
--- /dev/null
+++ b/libbb/base64.c
@@ -0,0 +1,78 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Utility routines.
+ *
+ * Copyright 2003, Glenn McGrath
+ * Copyright 2010, Denys Vlasenko
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+#include "libbb.h"
+
+//kbuild:lib-y += base64.o
+
+void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
+{
+/* Note that EOF _can_ be passed as exit_char too */
+#define exit_char    ((int)(signed char)flags)
+#define uu_style_end (flags & BASE64_FLAG_UUEND)
+
+	int term_count = 0;
+
+	while (1) {
+		unsigned char translated[4];
+		int count = 0;
+
+		/* Process one group of 4 chars */
+		while (count < 4) {
+			char *table_ptr;
+			int ch;
+
+			/* Get next _valid_ character.
+			 * bb_uuenc_tbl_base64[] contains this string:
+			 *  0         1         2         3         4         5         6
+			 *  012345678901234567890123456789012345678901234567890123456789012345
+			 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
+			 */
+			do {
+				ch = fgetc(src_stream);
+				if (ch == exit_char && count == 0)
+					return;
+				if (ch == EOF)
+					bb_error_msg_and_die("truncated base64 input");
+				table_ptr = strchr(bb_uuenc_tbl_base64, ch);
+//TODO: add BASE64_FLAG_foo to die on bad char?
+//Note that then we may need to still allow '\r' (for mail processing)
+			} while (!table_ptr);
+
+			/* Convert encoded character to decimal */
+			ch = table_ptr - bb_uuenc_tbl_base64;
+
+			if (ch == 65 /* '\n' */) {
+				/* Terminating "====" line? */
+				if (uu_style_end && term_count == 4)
+					return; /* yes */
+				continue;
+			}
+			/* ch is 64 if char was '=', otherwise 0..63 */
+			translated[count] = ch & 63; /* 64 -> 0 */
+			if (ch == 64) {
+				term_count++;
+				break;
+			}
+			term_count = 0;
+			count++;
+		}
+
+		/* Merge 6 bit chars to 8 bit.
+		 * count can be < 4 when we decode the tail:
+		 * "eQ==" -> "y", not "y NUL NUL"
+		 */
+		if (count > 1)
+			fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+		if (count > 2)
+			fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
+		if (count > 3)
+			fputc(translated[2] << 6 | translated[3], dst_stream);
+	} /* while (1) */
+}
-- 
cgit v1.2.3-55-g6feb


From c8f9a8d3c0f9e5d47cc650bf0425926b03e8bbc6 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Thu, 16 Sep 2010 18:10:04 +0200
Subject: move read_base64 to libbb/uuencode.c

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
---
 libbb/base64.c   | 78 --------------------------------------------------------
 libbb/uuencode.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 mailutils/mail.c |  5 ++--
 3 files changed, 77 insertions(+), 82 deletions(-)
 delete mode 100644 libbb/base64.c

(limited to 'libbb')

diff --git a/libbb/base64.c b/libbb/base64.c
deleted file mode 100644
index b9d47ae08..000000000
--- a/libbb/base64.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * Utility routines.
- *
- * Copyright 2003, Glenn McGrath
- * Copyright 2010, Denys Vlasenko
- *
- * Licensed under GPLv2 or later, see file LICENSE in this source tree.
- */
-#include "libbb.h"
-
-//kbuild:lib-y += base64.o
-
-void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
-{
-/* Note that EOF _can_ be passed as exit_char too */
-#define exit_char    ((int)(signed char)flags)
-#define uu_style_end (flags & BASE64_FLAG_UUEND)
-
-	int term_count = 0;
-
-	while (1) {
-		unsigned char translated[4];
-		int count = 0;
-
-		/* Process one group of 4 chars */
-		while (count < 4) {
-			char *table_ptr;
-			int ch;
-
-			/* Get next _valid_ character.
-			 * bb_uuenc_tbl_base64[] contains this string:
-			 *  0         1         2         3         4         5         6
-			 *  012345678901234567890123456789012345678901234567890123456789012345
-			 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
-			 */
-			do {
-				ch = fgetc(src_stream);
-				if (ch == exit_char && count == 0)
-					return;
-				if (ch == EOF)
-					bb_error_msg_and_die("truncated base64 input");
-				table_ptr = strchr(bb_uuenc_tbl_base64, ch);
-//TODO: add BASE64_FLAG_foo to die on bad char?
-//Note that then we may need to still allow '\r' (for mail processing)
-			} while (!table_ptr);
-
-			/* Convert encoded character to decimal */
-			ch = table_ptr - bb_uuenc_tbl_base64;
-
-			if (ch == 65 /* '\n' */) {
-				/* Terminating "====" line? */
-				if (uu_style_end && term_count == 4)
-					return; /* yes */
-				continue;
-			}
-			/* ch is 64 if char was '=', otherwise 0..63 */
-			translated[count] = ch & 63; /* 64 -> 0 */
-			if (ch == 64) {
-				term_count++;
-				break;
-			}
-			term_count = 0;
-			count++;
-		}
-
-		/* Merge 6 bit chars to 8 bit.
-		 * count can be < 4 when we decode the tail:
-		 * "eQ==" -> "y", not "y NUL NUL"
-		 */
-		if (count > 1)
-			fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
-		if (count > 2)
-			fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
-		if (count > 3)
-			fputc(translated[2] << 6 | translated[3], dst_stream);
-	} /* while (1) */
-}
diff --git a/libbb/uuencode.c b/libbb/uuencode.c
index 181f49de0..03e708fd5 100644
--- a/libbb/uuencode.c
+++ b/libbb/uuencode.c
@@ -1,6 +1,8 @@
 /* vi: set sw=4 ts=4: */
 /*
- * Copyright 2006 Rob Landley <rob@landley.net>
+ * Copyright 2003, Glenn McGrath
+ * Copyright 2006, Rob Landley <rob@landley.net>
+ * Copyright 2010, Denys Vlasenko
  *
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
@@ -69,3 +71,75 @@ void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl
 		length++;
 	}
 }
+
+/*
+ * Decode base64 encoded stream.
+ * Can stop on EOF, specified char, or on uuencode-style "====" line:
+ * flags argument controls it.
+ */
+void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
+{
+/* Note that EOF _can_ be passed as exit_char too */
+#define exit_char    ((int)(signed char)flags)
+#define uu_style_end (flags & BASE64_FLAG_UU_STOP)
+
+	int term_count = 0;
+
+	while (1) {
+		unsigned char translated[4];
+		int count = 0;
+
+		/* Process one group of 4 chars */
+		while (count < 4) {
+			char *table_ptr;
+			int ch;
+
+			/* Get next _valid_ character.
+			 * bb_uuenc_tbl_base64[] contains this string:
+			 *  0         1         2         3         4         5         6
+			 *  012345678901234567890123456789012345678901234567890123456789012345
+			 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
+			 */
+			do {
+				ch = fgetc(src_stream);
+				if (ch == exit_char && count == 0)
+					return;
+				if (ch == EOF)
+					bb_error_msg_and_die("truncated base64 input");
+				table_ptr = strchr(bb_uuenc_tbl_base64, ch);
+//TODO: add BASE64_FLAG_foo to die on bad char?
+//Note that then we may need to still allow '\r' (for mail processing)
+			} while (!table_ptr);
+
+			/* Convert encoded character to decimal */
+			ch = table_ptr - bb_uuenc_tbl_base64;
+
+			if (ch == 65 /* '\n' */) {
+				/* Terminating "====" line? */
+				if (uu_style_end && term_count == 4)
+					return; /* yes */
+				term_count = 0;
+				continue;
+			}
+			/* ch is 64 if char was '=', otherwise 0..63 */
+			translated[count] = ch & 63; /* 64 -> 0 */
+			if (ch == 64) {
+				term_count++;
+				break;
+			}
+			count++;
+			term_count = 0;
+		}
+
+		/* Merge 6 bit chars to 8 bit.
+		 * count can be < 4 when we decode the tail:
+		 * "eQ==" -> "y", not "y NUL NUL"
+		 */
+		if (count > 1)
+			fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+		if (count > 2)
+			fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
+		if (count > 3)
+			fputc(translated[2] << 6 | translated[3], dst_stream);
+	} /* while (1) */
+}
diff --git a/mailutils/mail.c b/mailutils/mail.c
index 89db66166..9b4bebce5 100644
--- a/mailutils/mail.c
+++ b/mailutils/mail.c
@@ -116,16 +116,15 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol)
 		SRC_BUF_SIZE = 45,  /* This *MUST* be a multiple of 3 */
 		DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
 	};
-
 #define src_buf text
+	char src[SRC_BUF_SIZE];
 	FILE *fp = fp;
 	ssize_t len = len;
 	char dst_buf[DST_BUF_SIZE + 1];
 
 	if (fname) {
 		fp = (NOT_LONE_DASH(fname)) ? xfopen_for_read(fname) : (FILE *)text;
-		src_buf = bb_common_bufsiz1;
-	// N.B. strlen(NULL) segfaults!
+		src_buf = src;
 	} else if (text) {
 		// though we do not call uuencode(NULL, NULL) explicitly
 		// still we do not want to break things suddenly
-- 
cgit v1.2.3-55-g6feb


From 63adf838143e78b0857af39a2d365fc86bcf0cd4 Mon Sep 17 00:00:00 2001
From: Dan Fandrich <dan@coneharvesters.com>
Date: Sun, 19 Sep 2010 17:13:21 +0200
Subject: fix build failure for pmap

Signed-off-by: Dan Fandrich <dan@coneharvesters.com>
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
---
 libbb/procps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'libbb')

diff --git a/libbb/procps.c b/libbb/procps.c
index 14d4481bd..792466048 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -120,7 +120,7 @@ void FAST_FUNC free_procps_scan(procps_status_t* sp)
 	free(sp);
 }
 
-#if ENABLE_FEATURE_TOPMEM
+#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
 static unsigned long fast_strtoul_16(char **endptr)
 {
 	unsigned char c;
-- 
cgit v1.2.3-55-g6feb


From d4d289acf5eb59ebae414f9aae8a74de30dce36a Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Tue, 12 Oct 2010 04:18:05 +0200
Subject: tweaks to build system, mainly making menuconfig text and order
 clearer

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 Config.in             | 61 ++++++++++++++++++++++++++++-----------------------
 include/applets.src.h |  5 -----
 include/busybox.h     |  7 +++++-
 libbb/appletlib.c     |  8 ++++---
 miscutils/Config.src  |  1 -
 networking/Config.src |  2 +-
 6 files changed, 46 insertions(+), 38 deletions(-)

(limited to 'libbb')

diff --git a/Config.in b/Config.in
index 828b30471..d9c823199 100644
--- a/Config.in
+++ b/Config.in
@@ -123,6 +123,14 @@ config FEATURE_INSTALLER
 	  busybox at runtime to create hard links or symlinks for all the
 	  applets that are compiled into busybox.
 
+config INSTALL_NO_USR
+	bool "Don't use /usr"
+	default n
+	depends on FEATURE_INSTALLER
+	help
+	  Disable use of /usr. busybox --install will install applets
+	  only to /bin and /sbin, never to /usr/bin or /usr/sbin.
+
 config LOCALE_SUPPORT
 	bool "Enable locale support (system needs locale for this to work)"
 	default n
@@ -275,15 +283,6 @@ config FEATURE_CLEAN_UP
 	  Don't enable this unless you have a really good reason to clean
 	  things up manually.
 
-config FEATURE_UTMP
-	bool "Support utmp file"
-	default y
-	help
-	  The file /var/run/utmp is used to track who is currently logged in.
-	  With this option on, certain applets (getty, login, telnetd etc)
-	  will create and delete entries there.
-	  "who" applet requires this option.
-
 config FEATURE_WTMP
 	bool "Support wtmp file"
 	default y
@@ -295,6 +294,15 @@ config FEATURE_WTMP
 	  will append new entries there.
 	  "last" applet requires this option.
 
+config FEATURE_UTMP
+	bool "Support utmp file"
+	default y
+	help
+	  The file /var/run/utmp is used to track who is currently logged in.
+	  With this option on, certain applets (getty, login, telnetd etc)
+	  will create and delete entries there.
+	  "who" applet requires this option.
+
 config FEATURE_PIDFILE
 	bool "Support writing pidfiles"
 	default y
@@ -307,14 +315,19 @@ config FEATURE_SUID
 	default y
 	help
 	  With this option you can install the busybox binary belonging
-	  to root with the suid bit set, and it will automatically drop
-	  priviledges for applets that don't need root access.
+	  to root with the suid bit set, enabling some applets to perform
+	  root-level operations even when run by ordinary users
+	  (for example, mounting of user mounts in fstab needs this).
+
+	  Busybox will automatically drop priviledges for applets
+	  that don't need root access.
 
 	  If you are really paranoid and don't want to do this, build two
 	  busybox binaries with different applets in them (and the appropriate
 	  symlinks pointing to each binary), and only set the suid bit on the
-	  one that needs it. The applets currently marked to need the suid bit
-	  are:
+	  one that needs it.
+
+	  The applets currently marked to need the suid bit are:
 
 	  crontab, dnsd, findfs, ipcrm, ipcs, login, passwd, ping, su,
 	  traceroute, vlock.
@@ -651,20 +664,13 @@ endchoice
 
 endmenu
 
-menu 'Installation Options'
-
-config INSTALL_NO_USR
-	bool "Don't use /usr"
-	default n
-	help
-	  Disable use of /usr. Don't activate this option if you don't know
-	  that you really want this behaviour.
+menu 'Installation Options ("make install" behavior)'
 
 choice
-	prompt "Applets links"
+	prompt "What kind of applet links to install"
 	default INSTALL_APPLET_SYMLINKS
 	help
-	  Choose how you install applets links.
+	  Choose what kind of links to applets are created by "make install".
 
 config INSTALL_APPLET_SYMLINKS
 	bool "as soft-links"
@@ -688,8 +694,9 @@ config INSTALL_APPLET_DONT
 	bool "not installed"
 	depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE || FEATURE_PREFER_APPLETS
 	help
-	  Do not install applet links. Useful when using the -install feature
-	  or a standalone shell for rescue purposes.
+	  Do not install applet links. Useful when you plan to use
+	  busybox --install for installing links, or plan to use
+	  a standalone shell and thus don't need applet links.
 
 endchoice
 
@@ -713,8 +720,8 @@ config INSTALL_SH_APPLET_HARDLINK
 config INSTALL_SH_APPLET_SCRIPT_WRAPPER
 	bool "as script wrapper"
 	help
-	  Install /bin/sh applet as script wrapper that call the busybox
-	  binary.
+	  Install /bin/sh applet as script wrapper that calls
+	  the busybox binary.
 
 endchoice
 
diff --git a/include/applets.src.h b/include/applets.src.h
index d2b1d198f..6a14a6588 100644
--- a/include/applets.src.h
+++ b/include/applets.src.h
@@ -56,11 +56,6 @@ s     - suid type:
 # define APPLET_NOFORK(name,main,l,s,name2)  { #name, #main, l, s, 1, 1 },
 #endif
 
-#if ENABLE_INSTALL_NO_USR
-# define _BB_DIR_USR_BIN _BB_DIR_BIN
-# define _BB_DIR_USR_SBIN _BB_DIR_SBIN
-#endif
-
 
 INSERT
 IF_TEST(APPLET_NOFORK([,  test, _BB_DIR_USR_BIN, _BB_SUID_DROP, test))
diff --git a/include/busybox.h b/include/busybox.h
index 76415dd72..757317fc7 100644
--- a/include/busybox.h
+++ b/include/busybox.h
@@ -16,8 +16,13 @@ typedef enum bb_install_loc_t {
 	_BB_DIR_ROOT = 0,
 	_BB_DIR_BIN,
 	_BB_DIR_SBIN,
+#if ENABLE_INSTALL_NO_USR
+	_BB_DIR_USR_BIN  = _BB_DIR_BIN,
+	_BB_DIR_USR_SBIN = _BB_DIR_SBIN,
+#else
 	_BB_DIR_USR_BIN,
-	_BB_DIR_USR_SBIN
+	_BB_DIR_USR_SBIN,
+#endif
 } bb_install_loc_t;
 
 typedef enum bb_suid_t {
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 7326f4fa5..b32ff8808 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -592,9 +592,11 @@ static const char usr_sbin[] ALIGN1 = "/usr/sbin/";
 static const char *const install_dir[] = {
 	&usr_bin [8], /* "/" */
 	&usr_bin [4], /* "/bin/" */
-	&usr_sbin[4], /* "/sbin/" */
-	usr_bin,
-	usr_sbin
+	&usr_sbin[4]  /* "/sbin/" */
+# if !ENABLE_INSTALL_NO_USR
+	,usr_bin
+	,usr_sbin
+# endif
 };
 
 
diff --git a/miscutils/Config.src b/miscutils/Config.src
index 151f61bcc..4912daf88 100644
--- a/miscutils/Config.src
+++ b/miscutils/Config.src
@@ -136,7 +136,6 @@ config CHRT
 config CROND
 	bool "crond"
 	default y
-	select FEATURE_SUID
 	select FEATURE_SYSLOG
 	help
 	  Crond is a background daemon that parses individual crontab
diff --git a/networking/Config.src b/networking/Config.src
index 9fc122bf3..6dd7df754 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -804,7 +804,7 @@ config TELNETD
 
 		  mount -t devpts devpts /dev/pts
 
-	  You need to be sure that Busybox has LOGIN and
+	  You need to be sure that busybox has LOGIN and
 	  FEATURE_SUID enabled. And finally, you should make
 	  certain that Busybox has been installed setuid root:
 
-- 
cgit v1.2.3-55-g6feb


From 3d160984944a915cfac13da2b835fa29fc556321 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Fri, 15 Oct 2010 18:05:51 +0200
Subject: libbb/md5: small code shrink

function                                             old     new   delta
md5_end                                              151     123     -28

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
---
 libbb/md5.c | 48 ++++++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 22 deletions(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index d8655ba91..9e5b496ce 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -56,6 +56,10 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	const uint32_t *words = buffer;
 
 #if MD5_SIZE_VS_SPEED > 0
+	/* Before we start, one word to the strange constants.
+	   They are defined in RFC 1321 as
+	   T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
+	 */
 	static const uint32_t C_array[] = {
 		/* round 1 */
 		0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
@@ -93,15 +97,13 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 		4, 11, 16, 23,
 		6, 10, 15, 21
 	};
-# endif	/* MD5_SIZE_VS_SPEED > 1 */
+# endif
 #endif
 	uint32_t A = ctx->A;
 	uint32_t B = ctx->B;
 	uint32_t C = ctx->C;
 	uint32_t D = ctx->D;
 
-	/* Process all bytes in the buffer with 64 bytes in each round of
-	   the loop.  */
 	uint32_t *cwp = correct_words;
 	uint32_t A_save = A;
 	uint32_t B_save = B;
@@ -149,7 +151,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 		C = B;
 		B = temp;
 	}
-# else
+# else /* MD5_SIZE_VS_SPEED == 2 */
 	pc = C_array;
 	pp = P_array;
 	ps = S_array;
@@ -193,15 +195,17 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 		C = B;
 		B = temp;
 	}
+# endif
+
+#else /* MD5_SIZE_VS_SPEED == 0 or 1 */
 
-# endif /* MD5_SIZE_VS_SPEED > 2 */
-#else
 	/* First round: using the given function, the context and a constant
-	   the next context is computed.  Because the algorithms processing
+	   the next context is computed.  Because the algorithm's processing
 	   unit is a 32-bit word and it is determined to work on words in
 	   little endian byte order we perhaps have to change the byte order
 	   before the computation.  To reduce the work for the next steps
 	   we store the swapped words in the array CORRECT_WORDS.  */
+# undef OP
 # define OP(a, b, c, d, s, T) \
 	do { \
 		a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \
@@ -210,16 +214,11 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 		a += b; \
 	} while (0)
 
-	/* Before we start, one word to the strange constants.
-	   They are defined in RFC 1321 as
-	   T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
-	 */
-
 # if MD5_SIZE_VS_SPEED == 1
 	const uint32_t *pc;
 	const char *pp;
 	int i;
-# endif	/* MD5_SIZE_VS_SPEED */
+# endif
 
 	/* Round 1.  */
 # if MD5_SIZE_VS_SPEED == 1
@@ -247,7 +246,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	OP(D, A, B, C, 12, 0xfd987193);
 	OP(C, D, A, B, 17, 0xa679438e);
 	OP(B, C, D, A, 22, 0x49b40821);
-# endif /* MD5_SIZE_VS_SPEED == 1 */
+# endif
 
 	/* For the second to fourth round we have the possibly swapped words
 	   in CORRECT_WORDS.  Redefine the macro to take an additional first
@@ -286,7 +285,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
 	OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
 	OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-# endif /* MD5_SIZE_VS_SPEED == 1 */
+# endif
 
 	/* Round 3.  */
 # if MD5_SIZE_VS_SPEED == 1
@@ -313,7 +312,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
 	OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
 	OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
-# endif /* MD5_SIZE_VS_SPEED == 1 */
+# endif
 
 	/* Round 4.  */
 # if MD5_SIZE_VS_SPEED == 1
@@ -340,8 +339,8 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
 	OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
 	OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
-# endif	/* MD5_SIZE_VS_SPEED == 1 */
-#endif	/* MD5_SIZE_VS_SPEED > 1 */
+# endif
+#endif
 
 	/* Add the starting values of the context.  */
 	A += A_save;
@@ -395,6 +394,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
  */
 void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
 {
+	uint64_t total;
 	char *buf = ctx->buffer;
 	int i;
 
@@ -402,12 +402,16 @@ void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
 	buf[ctx->buflen++] = 0x80;
 	memset(buf + ctx->buflen, 0, 128 - ctx->buflen);
 
-	/* Put the 64-bit file length in *bits* at the end of the buffer.  */
-	ctx->total <<= 3;
+	/* Put the 64-bit file length, expressed in *bits*,
+	 * at the end of the buffer.
+	 */
+	total = ctx->total << 3;
 	if (ctx->buflen > 56)
 		buf += 64;
-	for (i = 0; i < 8; i++)
-		buf[56 + i] = ctx->total >> (i*8);
+	for (i = 0; i < 8; i++) {
+		buf[56 + i] = total;
+		total >>= 8;
+	}
 
 	/* Process last bytes.  */
 	if (buf != ctx->buffer)
-- 
cgit v1.2.3-55-g6feb


From 70186711f45816bdf4562831af3bd995172eb47b Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Sat, 16 Oct 2010 01:08:32 +0200
Subject: libbb/md5: code shrink

function                                             old     new   delta
md5_end                                              123     117      -6
md5_begin                                             49      42      -7
md5_hash                                             119     104     -15

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
---
 include/libbb.h |  1 -
 libbb/md5.c     | 48 ++++++++++++++++++++++++++----------------------
 2 files changed, 26 insertions(+), 23 deletions(-)

(limited to 'libbb')

diff --git a/include/libbb.h b/include/libbb.h
index 8d7beffe7..034016f4a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1540,7 +1540,6 @@ typedef struct md5_ctx_t {
 	uint32_t C;
 	uint32_t D;
 	uint64_t total;
-	uint32_t buflen;
 	char buffer[128];
 } md5_ctx_t;
 #else
diff --git a/libbb/md5.c b/libbb/md5.c
index 9e5b496ce..1f9d59e6e 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -1,7 +1,7 @@
 /* vi: set sw=4 ts=4: */
 /*
- * md5.c - Compute MD5 checksum of strings according to the
- *         definition of MD5 in RFC 1321 from April 1992.
+ * Compute MD5 checksum of strings according to the
+ * definition of MD5 in RFC 1321 from April 1992.
  *
  * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
  *
@@ -34,7 +34,6 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx)
 	ctx->C = 0x98badcfe;
 	ctx->D = 0x10325476;
 	ctx->total = 0;
-	ctx->buflen = 0;
 }
 
 /* These are the four functions used in the four steps of the MD5 algorithm
@@ -355,35 +354,39 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
 	ctx->D = D;
 }
 
+/* The size of filled part of ctx->buffer: */
+#define BUFLEN(ctx) (((unsigned)ctx->total) & 63)
+
 /* Feed data through a temporary buffer to call md5_hash_aligned_block()
  * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
  * This function's internal buffer remembers previous data until it has 64
  * bytes worth to pass on.  Call md5_end() to flush this buffer. */
 void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
 {
-	char *buf = (char *)buffer;
+	const char *buf = buffer;
+	unsigned buflen = BUFLEN(ctx);
 
-	/* RFC 1321 specifies the possible length of the file up to 2^64 bits,
+	/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
 	 * Here we only track the number of bytes.  */
 	ctx->total += len;
 
 	/* Process all input. */
-	while (len) {
-		unsigned i = 64 - ctx->buflen;
-
-		/* Copy data into aligned buffer. */
+	while (1) {
+		unsigned i = 64 - buflen;
 		if (i > len)
 			i = len;
-		memcpy(ctx->buffer + ctx->buflen, buf, i);
+		/* Copy data into aligned buffer. */
+		memcpy(ctx->buffer + buflen, buf, i);
 		len -= i;
-		ctx->buflen += i;
 		buf += i;
-
-		/* When buffer fills up, process it. */
-		if (ctx->buflen == 64) {
-			md5_hash_block(ctx->buffer, ctx);
-			ctx->buflen = 0;
-		}
+		buflen += i;
+		/* clever way to do "if (buflen != 64) break; ... ; buflen = 0;" */
+		buflen -= 64;
+		if (buflen != 0)
+			break;
+		/* Buffer is filled up, process it. */
+		md5_hash_block(ctx->buffer, ctx);
+		/*buflen = 0; - already is */
 	}
 }
 
@@ -396,18 +399,19 @@ void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
 {
 	uint64_t total;
 	char *buf = ctx->buffer;
-	int i;
+	unsigned i;
+	unsigned buflen = BUFLEN(ctx);
 
 	/* Pad data to block size.  */
-	buf[ctx->buflen++] = 0x80;
-	memset(buf + ctx->buflen, 0, 128 - ctx->buflen);
+	buf[buflen++] = 0x80;
+	memset(buf + buflen, 0, 128 - buflen);
 
 	/* Put the 64-bit file length, expressed in *bits*,
 	 * at the end of the buffer.
 	 */
+	/* clever way to do "if (buflen > 56) buf += 64": */
+	buf += ((buflen + 7) & 64);
 	total = ctx->total << 3;
-	if (ctx->buflen > 56)
-		buf += 64;
 	for (i = 0; i < 8; i++) {
 		buf[56 + i] = total;
 		total >>= 8;
-- 
cgit v1.2.3-55-g6feb


From c0683acce88efc1fe15d9a4332428b5a9fdc6c2e Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 20:45:27 +0200
Subject: *: pass md5/shaN context pointer as 1st arg, not last

function                                             old     new   delta
md5_hash_block                                       458     459      +1
filter_rename_config                                 252     250      -2
md5_crypt                                            591     587      -4

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 archival/dpkg.c          |  4 ++--
 coreutils/md5_sha1_sum.c |  6 +++---
 include/libbb.h          | 12 ++++++------
 libbb/md5.c              | 12 ++++++------
 libbb/pw_encrypt_md5.c   | 32 ++++++++++++++++----------------
 libbb/sha1.c             |  8 ++++----
 mailutils/popmaildir.c   |  6 +++---
 7 files changed, 40 insertions(+), 40 deletions(-)

(limited to 'libbb')

diff --git a/archival/dpkg.c b/archival/dpkg.c
index b36c26198..07f01501b 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1524,8 +1524,8 @@ static char FAST_FUNC filter_rename_config(archive_handle_t *archive_handle)
 		buf = xmalloc(4096);
 		md5_begin(&md5);
 		while ((count = safe_read(fd, buf, 4096)) > 0)
-			md5_hash(buf, count, &md5);
-		md5_end(buf, &md5); /* using buf as result storage */
+			md5_hash(&md5, buf, count);
+		md5_end(&md5, buf); /* using buf as result storage */
 		close(fd);
 
 		md5line = xmalloc(16 * 2 + 2 + strlen(name_ptr) + 1);
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 5e36d391a..e79210c0d 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -43,7 +43,7 @@ static uint8_t *hash_file(const char *filename /*, hash_algo_t hash_algo*/)
 	} context;
 	uint8_t *hash_value = NULL;
 	RESERVE_CONFIG_UBUFFER(in_buf, 4096);
-	void FAST_FUNC (*update)(const void*, size_t, void*);
+	void FAST_FUNC (*update)(void*, const void*, size_t);
 	void FAST_FUNC (*final)(void*, void*);
 	hash_algo_t hash_algo = applet_name[3];
 
@@ -78,11 +78,11 @@ static uint8_t *hash_file(const char *filename /*, hash_algo_t hash_algo*/)
 	}
 
 	while (0 < (count = safe_read(src_fd, in_buf, 4096))) {
-		update(in_buf, count, &context);
+		update(&context, in_buf, count);
 	}
 
 	if (count == 0) {
-		final(in_buf, &context);
+		final(&context, in_buf);
 		hash_value = hash_bin_to_hex(in_buf, hash_len);
 	}
 
diff --git a/include/libbb.h b/include/libbb.h
index 034016f4a..1031cad8b 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1519,8 +1519,8 @@ typedef struct sha1_ctx_t {
 	void (*process_block)(struct sha1_ctx_t*) FAST_FUNC;
 } sha1_ctx_t;
 void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
-void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;
-void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
+void sha1_hash(sha1_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
+void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
 typedef struct sha1_ctx_t sha256_ctx_t;
 void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
 #define sha256_hash sha1_hash
@@ -1531,8 +1531,8 @@ typedef struct sha512_ctx_t {
 	uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
 } sha512_ctx_t;
 void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
-void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC;
-void sha512_end(void *resbuf, sha512_ctx_t *ctx) FAST_FUNC;
+void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
+void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
 #if 1
 typedef struct md5_ctx_t {
 	uint32_t A;
@@ -1551,8 +1551,8 @@ typedef struct md5_ctx_t {
 } md5_ctx_t;
 #endif
 void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
-void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC;
-void md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC;
+void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
+void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
 
 
 uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
diff --git a/libbb/md5.c b/libbb/md5.c
index 1f9d59e6e..47f5fc6f8 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -49,7 +49,7 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx)
 #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s))))
 
 /* Hash a single block, 64 bytes long and 4-byte aligned. */
-static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
+static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 {
 	uint32_t correct_words[16];
 	const uint32_t *words = buffer;
@@ -361,7 +361,7 @@ static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
  * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
  * This function's internal buffer remembers previous data until it has 64
  * bytes worth to pass on.  Call md5_end() to flush this buffer. */
-void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
+void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 {
 	const char *buf = buffer;
 	unsigned buflen = BUFLEN(ctx);
@@ -385,7 +385,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
 		if (buflen != 0)
 			break;
 		/* Buffer is filled up, process it. */
-		md5_hash_block(ctx->buffer, ctx);
+		md5_hash_block(ctx, ctx->buffer);
 		/*buflen = 0; - already is */
 	}
 }
@@ -395,7 +395,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
  * endian byte order, so that a byte-wise output yields to the wanted
  * ASCII representation of the message digest.
  */
-void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
+void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
 {
 	uint64_t total;
 	char *buf = ctx->buffer;
@@ -419,8 +419,8 @@ void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
 
 	/* Process last bytes.  */
 	if (buf != ctx->buffer)
-		md5_hash_block(ctx->buffer, ctx);
-	md5_hash_block(buf, ctx);
+		md5_hash_block(ctx, ctx->buffer);
+	md5_hash_block(ctx, buf);
 
 	/* The MD5 result is in little endian byte order.
 	 * We (ab)use the fact that A-D are consecutive in memory.
diff --git a/libbb/pw_encrypt_md5.c b/libbb/pw_encrypt_md5.c
index 58964b567..889e09cab 100644
--- a/libbb/pw_encrypt_md5.c
+++ b/libbb/pw_encrypt_md5.c
@@ -92,10 +92,10 @@ md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned
 	/* Hash. the password first, since that is what is most unknown */
 	md5_begin(&ctx);
 	pw_len = strlen((char*)pw);
-	md5_hash(pw, pw_len, &ctx);
+	md5_hash(&ctx, pw, pw_len);
 
 	/* Then the salt including "$1$" */
-	md5_hash(salt, sl, &ctx);
+	md5_hash(&ctx, salt, sl);
 
 	/* Copy salt to result; skip "$1$" */
 	memcpy(result, salt, sl);
@@ -105,19 +105,19 @@ md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned
 
 	/* Then just as many characters of the MD5(pw, salt, pw) */
 	md5_begin(&ctx1);
-	md5_hash(pw, pw_len, &ctx1);
-	md5_hash(salt, sl, &ctx1);
-	md5_hash(pw, pw_len, &ctx1);
-	md5_end(final, &ctx1);
+	md5_hash(&ctx1, pw, pw_len);
+	md5_hash(&ctx1, salt, sl);
+	md5_hash(&ctx1, pw, pw_len);
+	md5_end(&ctx1, final);
 	for (pl = pw_len; pl > 0; pl -= 16)
-		md5_hash(final, pl > 16 ? 16 : pl, &ctx);
+		md5_hash(&ctx, final, pl > 16 ? 16 : pl);
 
 	/* Then something really weird... */
 	memset(final, 0, sizeof(final));
 	for (i = pw_len; i; i >>= 1) {
-		md5_hash(((i & 1) ? final : (const unsigned char *) pw), 1, &ctx);
+		md5_hash(&ctx, ((i & 1) ? final : (const unsigned char *) pw), 1);
 	}
-	md5_end(final, &ctx);
+	md5_end(&ctx, final);
 
 	/* And now, just to make sure things don't run too fast.
 	 * On a 60 Mhz Pentium this takes 34 msec, so you would
@@ -126,21 +126,21 @@ md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned
 	for (i = 0; i < 1000; i++) {
 		md5_begin(&ctx1);
 		if (i & 1)
-			md5_hash(pw, pw_len, &ctx1);
+			md5_hash(&ctx1, pw, pw_len);
 		else
-			md5_hash(final, 16, &ctx1);
+			md5_hash(&ctx1, final, 16);
 
 		if (i % 3)
-			md5_hash(salt, sl, &ctx1);
+			md5_hash(&ctx1, salt, sl);
 
 		if (i % 7)
-			md5_hash(pw, pw_len, &ctx1);
+			md5_hash(&ctx1, pw, pw_len);
 
 		if (i & 1)
-			md5_hash(final, 16, &ctx1);
+			md5_hash(&ctx1, final, 16);
 		else
-			md5_hash(pw, pw_len, &ctx1);
-		md5_end(final, &ctx1);
+			md5_hash(&ctx1, pw, pw_len);
+		md5_end(&ctx1, final);
 	}
 
 	p = result + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */
diff --git a/libbb/sha1.c b/libbb/sha1.c
index beeb70cf6..fac23c0ec 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -361,7 +361,7 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
 
 
 /* Used also for sha256 */
-void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
+void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len)
 {
 	unsigned in_buf = ctx->total64 & 63;
 	unsigned add = 64 - in_buf;
@@ -380,7 +380,7 @@ void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
 	memcpy(ctx->wbuffer + in_buf, buffer, len);
 }
 
-void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
+void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 {
 	unsigned in_buf = ctx->total64[0] & 127;
 	unsigned add = 128 - in_buf;
@@ -406,7 +406,7 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
 
 
 /* Used also for sha256 */
-void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
+void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 {
 	unsigned pad, in_buf;
 
@@ -442,7 +442,7 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
 	memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * in_buf);
 }
 
-void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx)
+void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 {
 	unsigned pad, in_buf;
 
diff --git a/mailutils/popmaildir.c b/mailutils/popmaildir.c
index f37db03d5..77ec71129 100644
--- a/mailutils/popmaildir.c
+++ b/mailutils/popmaildir.c
@@ -109,9 +109,9 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
 				s[1] = '\0';
 			// get md5 sum of "<stamp>password" string
 			md5_begin(&md5.ctx);
-			md5_hash(buf, strlen(buf), &md5.ctx);
-			md5_hash(G.pass, strlen(G.pass), &md5.ctx);
-			md5_end(res, &md5.ctx);
+			md5_hash(&md5.ctx, buf, strlen(buf));
+			md5_hash(&md5.ctx, G.pass, strlen(G.pass));
+			md5_end(&md5.ctx, res);
 			*bin2hex(md5.hex, (char*)res, 16) = '\0';
 			// APOP
 			s = xasprintf("%s %s", G.user, md5.hex);
-- 
cgit v1.2.3-55-g6feb


From bcccad35318004922cc04487e1df4eade4545966 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 20:46:35 +0200
Subject: md5: code shrink; and use 64-byte temp buf, not 128-byte.

function                                             old     new   delta
md5_hash                                             111     108      -3
md5_end                                              129     125      -4
md5_hash_block                                       459     454      -5
filter_rename_config                                 250     244      -6
md5_crypt                                            587     578      -9
popmaildir_main                                      828     816     -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-39)             Total: -39 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 include/libbb.h    |  2 +-
 include/platform.h |  4 ++++
 libbb/md5.c        | 51 +++++++++++++++++++++++++--------------------------
 3 files changed, 30 insertions(+), 27 deletions(-)

(limited to 'libbb')

diff --git a/include/libbb.h b/include/libbb.h
index 1031cad8b..f406fc6f1 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1540,7 +1540,7 @@ typedef struct md5_ctx_t {
 	uint32_t C;
 	uint32_t D;
 	uint64_t total;
-	char buffer[128];
+	char buffer[64];
 } md5_ctx_t;
 #else
 /* libbb/md5prime.c uses a bit different one: */
diff --git a/include/platform.h b/include/platform.h
index 85efa53cd..c255a17ce 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -197,6 +197,8 @@
 # define SWAP_LE16(x) bswap_16(x)
 # define SWAP_LE32(x) bswap_32(x)
 # define SWAP_LE64(x) bswap_64(x)
+# define IF_BIG_ENDIAN(...) __VA_ARGS__
+# define IF_LITTLE_ENDIAN(...)
 #else
 # define SWAP_BE16(x) bswap_16(x)
 # define SWAP_BE32(x) bswap_32(x)
@@ -204,6 +206,8 @@
 # define SWAP_LE16(x) (x)
 # define SWAP_LE32(x) (x)
 # define SWAP_LE64(x) (x)
+# define IF_BIG_ENDIAN(...)
+# define IF_LITTLE_ENDIAN(...) __VA_ARGS__
 #endif
 
 /* ---- Unaligned access ------------------------------------ */
diff --git a/libbb/md5.c b/libbb/md5.c
index 47f5fc6f8..3c24bc60b 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -49,11 +49,8 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx)
 #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s))))
 
 /* Hash a single block, 64 bytes long and 4-byte aligned. */
-static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
+static void md5_hash_block(md5_ctx_t *ctx)
 {
-	uint32_t correct_words[16];
-	const uint32_t *words = buffer;
-
 #if MD5_SIZE_VS_SPEED > 0
 	/* Before we start, one word to the strange constants.
 	   They are defined in RFC 1321 as
@@ -98,12 +95,13 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	};
 # endif
 #endif
+	const uint32_t *words = (const void*) ctx->buffer;
+
 	uint32_t A = ctx->A;
 	uint32_t B = ctx->B;
 	uint32_t C = ctx->C;
 	uint32_t D = ctx->D;
 
-	uint32_t *cwp = correct_words;
 	uint32_t A_save = A;
 	uint32_t B_save = B;
 	uint32_t C_save = C;
@@ -116,9 +114,10 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	int i;
 	uint32_t temp;
 
+# if BB_BIG_ENDIAN
 	for (i = 0; i < 16; i++)
-		cwp[i] = SWAP_LE32(words[i]);
-	words += 16;
+		words[i] = SWAP_LE32(words[i]);
+# endif
 
 # if MD5_SIZE_VS_SPEED > 2
 	pc = C_array;
@@ -142,7 +141,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 		case 3:
 			temp += FI(B, C, D);
 		}
-		temp += cwp[(int) (*pp++)] + *pc++;
+		temp += words[(int) (*pp++)] + *pc++;
 		temp = rotl32(temp, ps[i & 3]);
 		temp += B;
 		A = D;
@@ -156,7 +155,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	ps = S_array;
 
 	for (i = 0; i < 16; i++) {
-		temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++;
+		temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++;
 		temp = rotl32(temp, ps[i & 3]);
 		temp += B;
 		A = D;
@@ -166,7 +165,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	}
 	ps += 4;
 	for (i = 0; i < 16; i++) {
-		temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++;
+		temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++;
 		temp = rotl32(temp, ps[i & 3]);
 		temp += B;
 		A = D;
@@ -176,7 +175,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	}
 	ps += 4;
 	for (i = 0; i < 16; i++) {
-		temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++;
+		temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++;
 		temp = rotl32(temp, ps[i & 3]);
 		temp += B;
 		A = D;
@@ -186,7 +185,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	}
 	ps += 4;
 	for (i = 0; i < 16; i++) {
-		temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++;
+		temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++;
 		temp = rotl32(temp, ps[i & 3]);
 		temp += B;
 		A = D;
@@ -203,12 +202,12 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 	   unit is a 32-bit word and it is determined to work on words in
 	   little endian byte order we perhaps have to change the byte order
 	   before the computation.  To reduce the work for the next steps
-	   we store the swapped words in the array CORRECT_WORDS.  */
+	   we save swapped words in WORDS array.  */
 # undef OP
 # define OP(a, b, c, d, s, T) \
 	do { \
-		a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \
-		++words; \
+		a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \
+		words++; \
 		a = rotl32(a, s); \
 		a += b; \
 	} while (0)
@@ -248,7 +247,7 @@ static void md5_hash_block(md5_ctx_t *ctx, const void *buffer)
 # endif
 
 	/* For the second to fourth round we have the possibly swapped words
-	   in CORRECT_WORDS.  Redefine the macro to take an additional first
+	   in WORDS.  Redefine the macro to take an additional first
 	   argument specifying the function to use.  */
 # undef OP
 # define OP(f, a, b, c, d, k, s, T) \
@@ -385,7 +384,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 		if (buflen != 0)
 			break;
 		/* Buffer is filled up, process it. */
-		md5_hash_block(ctx, ctx->buffer);
+		md5_hash_block(ctx);
 		/*buflen = 0; - already is */
 	}
 }
@@ -398,29 +397,29 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
 {
 	uint64_t total;
-	char *buf = ctx->buffer;
 	unsigned i;
 	unsigned buflen = BUFLEN(ctx);
 
 	/* Pad data to block size.  */
-	buf[buflen++] = 0x80;
-	memset(buf + buflen, 0, 128 - buflen);
+	ctx->buffer[buflen++] = 0x80;
+	memset(ctx->buffer + buflen, 0, 64 - buflen);
+
+	if (buflen > 56) {
+		md5_hash_block(ctx);
+		memset(ctx->buffer, 0, 64);
+	}
 
 	/* Put the 64-bit file length, expressed in *bits*,
 	 * at the end of the buffer.
 	 */
-	/* clever way to do "if (buflen > 56) buf += 64": */
-	buf += ((buflen + 7) & 64);
 	total = ctx->total << 3;
 	for (i = 0; i < 8; i++) {
-		buf[56 + i] = total;
+		ctx->buffer[56 + i] = total;
 		total >>= 8;
 	}
 
 	/* Process last bytes.  */
-	if (buf != ctx->buffer)
-		md5_hash_block(ctx, ctx->buffer);
-	md5_hash_block(ctx, buf);
+	md5_hash_block(ctx);
 
 	/* The MD5 result is in little endian byte order.
 	 * We (ab)use the fact that A-D are consecutive in memory.
-- 
cgit v1.2.3-55-g6feb


From 1ac476bb8561f57703b84f090ed7a575fa512823 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 21:34:36 +0200
Subject: md5: fix "fast" md5 broken by prev commit

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/md5.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index 3c24bc60b..f192d0e47 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -245,6 +245,7 @@ static void md5_hash_block(md5_ctx_t *ctx)
 	OP(C, D, A, B, 17, 0xa679438e);
 	OP(B, C, D, A, 22, 0x49b40821);
 # endif
+	words -= 16;
 
 	/* For the second to fourth round we have the possibly swapped words
 	   in WORDS.  Redefine the macro to take an additional first
@@ -252,7 +253,7 @@ static void md5_hash_block(md5_ctx_t *ctx)
 # undef OP
 # define OP(f, a, b, c, d, k, s, T) \
 	do { \
-		a += f(b, c, d) + correct_words[k] + T; \
+		a += f(b, c, d) + words[k] + T; \
 		a = rotl32(a, s); \
 		a += b; \
 	} while (0)
-- 
cgit v1.2.3-55-g6feb


From 273abcbf664adc92ef3bc1d9752a2b571623ad52 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 22:43:34 +0200
Subject: shaN: small code shrink

function                                             old     new   delta
sha512_hash                                          134     128      -6
sha1_hash                                            114     106      -8

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/md5.c            |  61 +++++++++++++++++---------
 libbb/sha1.c           | 115 ++++++++++++++++++++++++++++++++++++-------------
 testsuite/md5sum.tests |  14 ++----
 3 files changed, 129 insertions(+), 61 deletions(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index f192d0e47..cf3825a34 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -354,8 +354,8 @@ static void md5_hash_block(md5_ctx_t *ctx)
 	ctx->D = D;
 }
 
-/* The size of filled part of ctx->buffer: */
-#define BUFLEN(ctx) (((unsigned)ctx->total) & 63)
+/* The first unused position in ctx->buffer: */
+#define BUFPOS(ctx) (((unsigned)ctx->total) & 63)
 
 /* Feed data through a temporary buffer to call md5_hash_aligned_block()
  * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
@@ -363,31 +363,52 @@ static void md5_hash_block(md5_ctx_t *ctx)
  * bytes worth to pass on.  Call md5_end() to flush this buffer. */
 void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 {
-	const char *buf = buffer;
-	unsigned buflen = BUFLEN(ctx);
+#if 1
+	/* Tiny bit smaller code */
+	unsigned bufpos = BUFPOS(ctx);
 
 	/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
 	 * Here we only track the number of bytes.  */
 	ctx->total += len;
 
-	/* Process all input. */
 	while (1) {
-		unsigned i = 64 - buflen;
-		if (i > len)
-			i = len;
+		unsigned remaining = 64 - bufpos;
+		if (remaining > len)
+			remaining = len;
 		/* Copy data into aligned buffer. */
-		memcpy(ctx->buffer + buflen, buf, i);
-		len -= i;
-		buf += i;
-		buflen += i;
-		/* clever way to do "if (buflen != 64) break; ... ; buflen = 0;" */
-		buflen -= 64;
-		if (buflen != 0)
+		memcpy(ctx->buffer + bufpos, buffer, remaining);
+		len -= remaining;
+		buffer = (const char *)buffer + remaining;
+		bufpos += remaining;
+		/* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
+		bufpos -= 64;
+		if (bufpos != 0)
 			break;
 		/* Buffer is filled up, process it. */
 		md5_hash_block(ctx);
-		/*buflen = 0; - already is */
+		/*bufpos = 0; - already is */
 	}
+#else
+	unsigned bufpos = BUFPOS(ctx);
+	unsigned add = 64 - bufpos;
+
+	/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
+	 * Here we only track the number of bytes.  */
+	ctx->total += len;
+
+	/* Hash whole blocks */
+	while (len >= add) {
+		memcpy(ctx->buffer + bufpos, buffer, add);
+		buffer = (const char *)buffer + add;
+		len -= add;
+		add = 64;
+		bufpos = 0;
+		md5_hash_block(ctx);
+	}
+
+	/* Save last, partial blosk */
+	memcpy(ctx->buffer + bufpos, buffer, len);
+#endif
 }
 
 /* Process the remaining bytes in the buffer and put result from CTX
@@ -399,13 +420,13 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
 {
 	uint64_t total;
 	unsigned i;
-	unsigned buflen = BUFLEN(ctx);
+	unsigned bufpos = BUFPOS(ctx);
 
 	/* Pad data to block size.  */
-	ctx->buffer[buflen++] = 0x80;
-	memset(ctx->buffer + buflen, 0, 64 - buflen);
+	ctx->buffer[bufpos++] = 0x80;
+	memset(ctx->buffer + bufpos, 0, 64 - bufpos);
 
-	if (buflen > 56) {
+	if (bufpos > 56) {
 		md5_hash_block(ctx);
 		memset(ctx->buffer, 0, 64);
 	}
diff --git a/libbb/sha1.c b/libbb/sha1.c
index fac23c0ec..8c67d07bc 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -363,62 +363,117 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
 /* Used also for sha256 */
 void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len)
 {
-	unsigned in_buf = ctx->total64 & 63;
-	unsigned add = 64 - in_buf;
+#if 0
+	unsigned bufpos = ctx->total64 & 63;
+	unsigned add = 64 - bufpos;
 
 	ctx->total64 += len;
 
-	while (len >= add) {	/* transfer whole blocks while possible  */
-		memcpy(ctx->wbuffer + in_buf, buffer, add);
+	/* Hash whole blocks */
+	while (len >= add) {
+		memcpy(ctx->wbuffer + bufpos, buffer, add);
 		buffer = (const char *)buffer + add;
 		len -= add;
 		add = 64;
-		in_buf = 0;
+		bufpos = 0;
 		ctx->process_block(ctx);
 	}
 
-	memcpy(ctx->wbuffer + in_buf, buffer, len);
+	/* Save last, partial blosk */
+	memcpy(ctx->wbuffer + bufpos, buffer, len);
+#else
+	/* Tiny bit smaller code */
+	unsigned bufpos = ctx->total64 & 63;
+
+	ctx->total64 += len;
+
+	while (1) {
+		unsigned remaining = 64 - bufpos;
+		if (remaining > len)
+			remaining = len;
+		/* Copy data into aligned buffer */
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
+		len -= remaining;
+		buffer = (const char *)buffer + remaining;
+		bufpos += remaining;
+		/* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
+		bufpos -= 64;
+		if (bufpos != 0)
+			break;
+		/* Buffer is filled up, process it */
+		ctx->process_block(ctx);
+		/*bufpos = 0; - already is */
+	}
+#endif
 }
 
 void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 {
-	unsigned in_buf = ctx->total64[0] & 127;
-	unsigned add = 128 - in_buf;
+#if 0
+	unsigned bufpos = ctx->total64[0] & 127;
+	unsigned add = 128 - bufpos;
 
-	/* First increment the byte count.  FIPS 180-2 specifies the possible
-	   length of the file up to 2^128 _bits_.
-	   We compute the number of _bytes_ and convert to bits later.  */
 	ctx->total64[0] += len;
 	if (ctx->total64[0] < len)
 		ctx->total64[1]++;
 
-	while (len >= add) {	/* transfer whole blocks while possible  */
-		memcpy(ctx->wbuffer + in_buf, buffer, add);
+	/* Hash whole blocks */
+	while (len >= add) {
+		memcpy(ctx->wbuffer + bufpos, buffer, add);
 		buffer = (const char *)buffer + add;
 		len -= add;
 		add = 128;
-		in_buf = 0;
+		bufpos = 0;
 		sha512_process_block128(ctx);
 	}
 
-	memcpy(ctx->wbuffer + in_buf, buffer, len);
+	/* Save last, partial blosk */
+	memcpy(ctx->wbuffer + bufpos, buffer, len);
+#else
+	unsigned bufpos = ctx->total64[0] & 127;
+
+	/* First increment the byte count.  FIPS 180-2 specifies the possible
+	   length of the file up to 2^128 _bits_.
+	   We compute the number of _bytes_ and convert to bits later.  */
+	ctx->total64[0] += len;
+	if (ctx->total64[0] < len)
+		ctx->total64[1]++;
+
+	while (1) {
+		unsigned remaining = 128 - bufpos;
+		if (remaining > len)
+			remaining = len;
+		/* Copy data into aligned buffer. */
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
+		len -= remaining;
+		buffer = (const char *)buffer + remaining;
+		bufpos += remaining;
+		/* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */
+		bufpos -= 128;
+		if (bufpos != 0)
+			break;
+		/* Buffer is filled up, process it. */
+		sha512_process_block128(ctx);
+		/*bufpos = 0; - already is */
+	}
+#endif
 }
 
 
 /* Used also for sha256 */
 void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 {
-	unsigned pad, in_buf;
+	unsigned pad, bufpos;
 
-	in_buf = ctx->total64 & 63;
+	bufpos = ctx->total64 & 63;
 	/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
-	ctx->wbuffer[in_buf++] = 0x80;
+	ctx->wbuffer[bufpos++] = 0x80;
 
 	/* This loop iterates either once or twice, no more, no less */
 	while (1) {
-		pad = 64 - in_buf;
-		memset(ctx->wbuffer + in_buf, 0, pad);
-		in_buf = 0;
+		pad = 64 - bufpos;
+		memset(ctx->wbuffer + bufpos, 0, pad);
+		bufpos = 0;
 		/* Do we have enough space for the length count? */
 		if (pad >= 8) {
 			/* Store the 64-bit counter of bits in the buffer in BE format */
@@ -432,30 +487,30 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 			break;
 	}
 
-	in_buf = (ctx->process_block == sha1_process_block64) ? 5 : 8;
+	bufpos = (ctx->process_block == sha1_process_block64) ? 5 : 8;
 	/* This way we do not impose alignment constraints on resbuf: */
 	if (BB_LITTLE_ENDIAN) {
 		unsigned i;
-		for (i = 0; i < in_buf; ++i)
+		for (i = 0; i < bufpos; ++i)
 			ctx->hash[i] = htonl(ctx->hash[i]);
 	}
-	memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * in_buf);
+	memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * bufpos);
 }
 
 void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 {
-	unsigned pad, in_buf;
+	unsigned pad, bufpos;
 
-	in_buf = ctx->total64[0] & 127;
+	bufpos = ctx->total64[0] & 127;
 	/* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0...
 	 * (FIPS 180-2:5.1.2)
 	 */
-	ctx->wbuffer[in_buf++] = 0x80;
+	ctx->wbuffer[bufpos++] = 0x80;
 
 	while (1) {
-		pad = 128 - in_buf;
-		memset(ctx->wbuffer + in_buf, 0, pad);
-		in_buf = 0;
+		pad = 128 - bufpos;
+		memset(ctx->wbuffer + bufpos, 0, pad);
+		bufpos = 0;
 		if (pad >= 16) {
 			/* Store the 128-bit counter of bits in the buffer in BE format */
 			uint64_t t;
diff --git a/testsuite/md5sum.tests b/testsuite/md5sum.tests
index 5bbdb3b58..35ec67cb4 100755
--- a/testsuite/md5sum.tests
+++ b/testsuite/md5sum.tests
@@ -18,25 +18,17 @@ fi
 sum="$1"
 expected="$2"
 
-mkdir testdir 2>/dev/null
-
-result=`(
-cd testdir || { echo "cannot cd testdir!" >&2; exit 1; }
-
 text="The quick brown fox jumps over the lazy dog"
+text=`yes "$text" | head -c 9999`
 
+result=`(
 n=0
 while test $n -le 999; do
-	yes "$text" | head -c $n | "$sum"
+	echo "$text" | head -c $n | "$sum"
 	: $((n++))
 done | "$sum"
-
 )`
 
-rm -rf testdir
-
-FAILCOUNT=0
-
 if test x"$result" = x"$expected  -"; then
     echo "PASS: $sum"
     exit 0
-- 
cgit v1.2.3-55-g6feb


From 4bc3b85894920df5a3102000e1d86e1c3321fc76 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 23:31:15 +0200
Subject: sha512: inline rotr64

function                                             old     new   delta
sha1_process_block64                                 461     446     -15

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/sha1.c | 108 ++++++++++++++++++++++++++++-------------------------------
 1 file changed, 51 insertions(+), 57 deletions(-)

(limited to 'libbb')

diff --git a/libbb/sha1.c b/libbb/sha1.c
index 8c67d07bc..7e9b37d57 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -30,11 +30,29 @@
 
 #include "libbb.h"
 
-#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
-#define rotr32(x,n) (((x) >> (n)) | ((x) << (32 - (n))))
-/* for sha512: */
-#define rotr64(x,n) (((x) >> (n)) | ((x) << (64 - (n))))
+/* gcc 4.2.1 optimizes rotr64 better with inline than with macro
+ * (for rotX32, there is no difference). Why? My guess is that
+ * macro requires clever common subexpression elimination heuristics
+ * in gcc, while inline basically forces it to happen.
+ */
+//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
+static ALWAYS_INLINE uint32_t rotl32(uint32_t x, unsigned n)
+{
+        return (x << n) | (x >> (32 - n));
+}
+//#define rotr32(x,n) (((x) >> (n)) | ((x) << (32 - (n))))
+static ALWAYS_INLINE uint32_t rotr32(uint32_t x, unsigned n)
+{
+        return (x >> n) | (x << (32 - n));
+}
+/* rotr64 in needed for sha512 only: */
+//#define rotr64(x,n) (((x) >> (n)) | ((x) << (64 - (n))))
+static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n)
+{
+        return (x >> n) | (x << (64 - n));
+}
 #if BB_LITTLE_ENDIAN
+/* ALWAYS_INLINE below would hurt code size, using plain inline: */
 static inline uint64_t hton64(uint64_t v)
 {
 	return (((uint64_t)htonl(v)) << 32) | htonl(v >> 32);
@@ -44,14 +62,6 @@ static inline uint64_t hton64(uint64_t v)
 #endif
 #define ntoh64(v) hton64(v)
 
-/* To check alignment gcc has an appropriate operator.  Other
-   compilers don't.  */
-#if defined(__GNUC__) && __GNUC__ >= 2
-# define UNALIGNED_P(p,type) (((uintptr_t) p) % __alignof__(type) != 0)
-#else
-# define UNALIGNED_P(p,type) (((uintptr_t) p) % sizeof(type) != 0)
-#endif
-
 
 /* Some arch headers have conflicting defines */
 #undef ch
@@ -65,11 +75,8 @@ static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx)
 	uint32_t W[80], a, b, c, d, e;
 	const uint32_t *words = (uint32_t*) ctx->wbuffer;
 
-	for (t = 0; t < 16; ++t) {
-		W[t] = ntohl(*words);
-		words++;
-	}
-
+	for (t = 0; t < 16; ++t)
+		W[t] = ntohl(words[t]);
 	for (/*t = 16*/; t < 80; ++t) {
 		uint32_t T = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
 		W[t] = rotl32(T, 1);
@@ -190,11 +197,8 @@ static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx)
 #define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10))
 
 	/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2.  */
-	for (t = 0; t < 16; ++t) {
-		W[t] = ntohl(*words);
-		words++;
-	}
-
+	for (t = 0; t < 16; ++t)
+		W[t] = ntohl(words[t]);
 	for (/*t = 16*/; t < 64; ++t)
 		W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
 
@@ -269,10 +273,8 @@ static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx)
 #define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6))
 
 	/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2.  */
-	for (t = 0; t < 16; ++t) {
-		W[t] = ntoh64(*words);
-		words++;
-	}
+	for (t = 0; t < 16; ++t)
+		W[t] = ntoh64(words[t]);
 	for (/*t = 16*/; t < 80; ++t)
 		W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
 
@@ -363,18 +365,19 @@ void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
 /* Used also for sha256 */
 void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len)
 {
-#if 0
 	unsigned bufpos = ctx->total64 & 63;
-	unsigned add = 64 - bufpos;
+	unsigned remaining;
 
 	ctx->total64 += len;
+#if 0
+	remaining = 64 - bufpos;
 
 	/* Hash whole blocks */
-	while (len >= add) {
-		memcpy(ctx->wbuffer + bufpos, buffer, add);
-		buffer = (const char *)buffer + add;
-		len -= add;
-		add = 64;
+	while (len >= remaining) {
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
+		buffer = (const char *)buffer + remaining;
+		len -= remaining;
+		remaining = 64;
 		bufpos = 0;
 		ctx->process_block(ctx);
 	}
@@ -383,12 +386,8 @@ void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len)
 	memcpy(ctx->wbuffer + bufpos, buffer, len);
 #else
 	/* Tiny bit smaller code */
-	unsigned bufpos = ctx->total64 & 63;
-
-	ctx->total64 += len;
-
 	while (1) {
-		unsigned remaining = 64 - bufpos;
+		remaining = 64 - bufpos;
 		if (remaining > len)
 			remaining = len;
 		/* Copy data into aligned buffer */
@@ -409,20 +408,24 @@ void FAST_FUNC sha1_hash(sha1_ctx_t *ctx, const void *buffer, size_t len)
 
 void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 {
-#if 0
 	unsigned bufpos = ctx->total64[0] & 127;
-	unsigned add = 128 - bufpos;
+	unsigned remaining;
 
+	/* First increment the byte count.  FIPS 180-2 specifies the possible
+	   length of the file up to 2^128 _bits_.
+	   We compute the number of _bytes_ and convert to bits later.  */
 	ctx->total64[0] += len;
 	if (ctx->total64[0] < len)
 		ctx->total64[1]++;
+#if 0
+	remaining = 128 - bufpos;
 
 	/* Hash whole blocks */
-	while (len >= add) {
-		memcpy(ctx->wbuffer + bufpos, buffer, add);
-		buffer = (const char *)buffer + add;
-		len -= add;
-		add = 128;
+	while (len >= remaining) {
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
+		buffer = (const char *)buffer + remaining;
+		len -= remaining;
+		remaining = 128;
 		bufpos = 0;
 		sha512_process_block128(ctx);
 	}
@@ -430,20 +433,11 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 	/* Save last, partial blosk */
 	memcpy(ctx->wbuffer + bufpos, buffer, len);
 #else
-	unsigned bufpos = ctx->total64[0] & 127;
-
-	/* First increment the byte count.  FIPS 180-2 specifies the possible
-	   length of the file up to 2^128 _bits_.
-	   We compute the number of _bytes_ and convert to bits later.  */
-	ctx->total64[0] += len;
-	if (ctx->total64[0] < len)
-		ctx->total64[1]++;
-
 	while (1) {
-		unsigned remaining = 128 - bufpos;
+		remaining = 128 - bufpos;
 		if (remaining > len)
 			remaining = len;
-		/* Copy data into aligned buffer. */
+		/* Copy data into aligned buffer */
 		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
 		len -= remaining;
 		buffer = (const char *)buffer + remaining;
@@ -452,7 +446,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 		bufpos -= 128;
 		if (bufpos != 0)
 			break;
-		/* Buffer is filled up, process it. */
+		/* Buffer is filled up, process it */
 		sha512_process_block128(ctx);
 		/*bufpos = 0; - already is */
 	}
-- 
cgit v1.2.3-55-g6feb


From 446c2349b608fc4e25ac5846f4491bfa389330a6 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 16 Oct 2010 23:39:43 +0200
Subject: whitespace fix

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/sha1.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'libbb')

diff --git a/libbb/sha1.c b/libbb/sha1.c
index 7e9b37d57..6d2f88457 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -38,18 +38,18 @@
 //#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
 static ALWAYS_INLINE uint32_t rotl32(uint32_t x, unsigned n)
 {
-        return (x << n) | (x >> (32 - n));
+	return (x << n) | (x >> (32 - n));
 }
 //#define rotr32(x,n) (((x) >> (n)) | ((x) << (32 - (n))))
 static ALWAYS_INLINE uint32_t rotr32(uint32_t x, unsigned n)
 {
-        return (x >> n) | (x << (32 - n));
+	return (x >> n) | (x << (32 - n));
 }
 /* rotr64 in needed for sha512 only: */
 //#define rotr64(x,n) (((x) >> (n)) | ((x) << (64 - (n))))
 static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n)
 {
-        return (x >> n) | (x << (64 - n));
+	return (x >> n) | (x << (64 - n));
 }
 #if BB_LITTLE_ENDIAN
 /* ALWAYS_INLINE below would hurt code size, using plain inline: */
-- 
cgit v1.2.3-55-g6feb


From a971a192e8af4279fb384be9ff0f0e8387b229cb Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sun, 17 Oct 2010 01:35:16 +0200
Subject: shaN: code shrink

function                                             old     new   delta
init512_lo                                            32      40      +8
init256                                               32      40      +8
sha256_begin                                          42      28     -14
sha512_begin                                          81      53     -28
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 16/-42)            Total: -26 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 include/libbb.h |  4 ++--
 libbb/sha1.c    | 15 ++++++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

(limited to 'libbb')

diff --git a/include/libbb.h b/include/libbb.h
index f406fc6f1..d05b2d48a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1514,7 +1514,7 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags);
 
 typedef struct sha1_ctx_t {
 	uint32_t hash[8];    /* 5, +3 elements for sha256 */
-	uint64_t total64;
+	uint64_t total64;    /* must be directly after hash[] */
 	uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
 	void (*process_block)(struct sha1_ctx_t*) FAST_FUNC;
 } sha1_ctx_t;
@@ -1527,7 +1527,7 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
 #define sha256_end sha1_end
 typedef struct sha512_ctx_t {
 	uint64_t hash[8];
-	uint64_t total64[2];
+	uint64_t total64[2];  /* must be directly after hash[] */
 	uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
 } sha512_ctx_t;
 void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
diff --git a/libbb/sha1.c b/libbb/sha1.c
index 6d2f88457..70efd581b 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -329,7 +329,9 @@ static const uint32_t init256[] = {
 	0x510e527f,
 	0x9b05688c,
 	0x1f83d9ab,
-	0x5be0cd19
+	0x5be0cd19,
+	0,
+	0,
 };
 static const uint32_t init512_lo[] = {
 	0xf3bcc908,
@@ -339,7 +341,9 @@ static const uint32_t init512_lo[] = {
 	0xade682d1,
 	0x2b3e6c1f,
 	0xfb41bd6b,
-	0x137e2179
+	0x137e2179,
+	0,
+	0,
 };
 
 /* Initialize structure containing state of computation.
@@ -347,7 +351,7 @@ static const uint32_t init512_lo[] = {
 void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
 {
 	memcpy(ctx->hash, init256, sizeof(init256));
-	ctx->total64 = 0;
+	/*ctx->total64 = 0; - done by extending init256 with two 32-bit zeros */
 	ctx->process_block = sha256_process_block64;
 }
 
@@ -356,9 +360,10 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
 void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
 {
 	int i;
-	for (i = 0; i < 8; i++)
+	/* Two extra iterations zero out ctx->total64[] */
+	for (i = 0; i < 8+2; i++)
 		ctx->hash[i] = ((uint64_t)(init256[i]) << 32) + init512_lo[i];
-	ctx->total64[0] = ctx->total64[1] = 0;
+	/*ctx->total64[0] = ctx->total64[1] = 0; - already done */
 }
 
 
-- 
cgit v1.2.3-55-g6feb


From 36ab585f68295487a0973bde86bcb0ab7577a8ff Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sun, 17 Oct 2010 03:00:36 +0200
Subject: md5: code shrink

function                                             old     new   delta
md5_end                                              125     104     -21

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/md5.c  | 37 ++++++++++++++++++-------------------
 libbb/sha1.c | 18 +++++++-----------
 2 files changed, 25 insertions(+), 30 deletions(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index cf3825a34..a1f0a923f 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -418,31 +418,30 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
  */
 void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
 {
-	uint64_t total;
-	unsigned i;
 	unsigned bufpos = BUFPOS(ctx);
-
-	/* Pad data to block size.  */
+	/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
 	ctx->buffer[bufpos++] = 0x80;
-	memset(ctx->buffer + bufpos, 0, 64 - bufpos);
 
-	if (bufpos > 56) {
+	/* This loop iterates either once or twice, no more, no less */
+	while (1) {
+		unsigned remaining = 64 - bufpos;
+		memset(ctx->buffer + bufpos, 0, remaining);
+		/* Do we have enough space for the length count? */
+		if (remaining >= 8) {
+			/* Store the 64-bit counter of bits in the buffer in BE format */
+			uint64_t t = ctx->total << 3;
+			unsigned i;
+			for (i = 0; i < 8; i++) {
+				ctx->buffer[56 + i] = t;
+				t >>= 8;
+			}
+		}
 		md5_hash_block(ctx);
-		memset(ctx->buffer, 0, 64);
-	}
-
-	/* Put the 64-bit file length, expressed in *bits*,
-	 * at the end of the buffer.
-	 */
-	total = ctx->total << 3;
-	for (i = 0; i < 8; i++) {
-		ctx->buffer[56 + i] = total;
-		total >>= 8;
+		if (remaining >= 8)
+			break;
+		bufpos = 0;
 	}
 
-	/* Process last bytes.  */
-	md5_hash_block(ctx);
-
 	/* The MD5 result is in little endian byte order.
 	 * We (ab)use the fact that A-D are consecutive in memory.
 	 */
diff --git a/libbb/sha1.c b/libbb/sha1.c
index 70efd581b..3e61aff6d 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -462,17 +462,15 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
 /* Used also for sha256 */
 void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 {
-	unsigned pad, bufpos;
+	unsigned bufpos = ctx->total64 & 63;
 
-	bufpos = ctx->total64 & 63;
 	/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
 	ctx->wbuffer[bufpos++] = 0x80;
 
 	/* This loop iterates either once or twice, no more, no less */
 	while (1) {
-		pad = 64 - bufpos;
+		unsigned pad = 64 - bufpos;
 		memset(ctx->wbuffer + bufpos, 0, pad);
-		bufpos = 0;
 		/* Do we have enough space for the length count? */
 		if (pad >= 8) {
 			/* Store the 64-bit counter of bits in the buffer in BE format */
@@ -484,6 +482,7 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 		ctx->process_block(ctx);
 		if (pad >= 8)
 			break;
+		bufpos = 0;
 	}
 
 	bufpos = (ctx->process_block == sha1_process_block64) ? 5 : 8;
@@ -498,18 +497,14 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 
 void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 {
-	unsigned pad, bufpos;
+	unsigned bufpos = ctx->total64[0] & 127;
 
-	bufpos = ctx->total64[0] & 127;
-	/* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0...
-	 * (FIPS 180-2:5.1.2)
-	 */
+	/* Pad the buffer to the next 128-byte boundary with 0x80,0,0,0... */
 	ctx->wbuffer[bufpos++] = 0x80;
 
 	while (1) {
-		pad = 128 - bufpos;
+		unsigned pad = 128 - bufpos;
 		memset(ctx->wbuffer + bufpos, 0, pad);
-		bufpos = 0;
 		if (pad >= 16) {
 			/* Store the 128-bit counter of bits in the buffer in BE format */
 			uint64_t t;
@@ -523,6 +518,7 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 		sha512_process_block128(ctx);
 		if (pad >= 16)
 			break;
+		bufpos = 0;
 	}
 
 	if (BB_LITTLE_ENDIAN) {
-- 
cgit v1.2.3-55-g6feb


From f6dacc23ff495cbdd3f1baf5985ded21a7e4a9c9 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sun, 17 Oct 2010 03:21:51 +0200
Subject: bring md5 and sha1 names closer. no code changes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 include/libbb.h |  4 +--
 libbb/md5.c     | 76 ++++++++++++++++++++++++++-------------------------------
 libbb/sha1.c    | 16 ++++++------
 3 files changed, 44 insertions(+), 52 deletions(-)

(limited to 'libbb')

diff --git a/include/libbb.h b/include/libbb.h
index d05b2d48a..dec4e3af5 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1539,8 +1539,8 @@ typedef struct md5_ctx_t {
 	uint32_t B;
 	uint32_t C;
 	uint32_t D;
-	uint64_t total;
-	char buffer[64];
+	uint64_t total64;
+	char wbuffer[64];
 } md5_ctx_t;
 #else
 /* libbb/md5prime.c uses a bit different one: */
diff --git a/libbb/md5.c b/libbb/md5.c
index a1f0a923f..f5d083e3f 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -33,7 +33,7 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx)
 	ctx->B = 0xefcdab89;
 	ctx->C = 0x98badcfe;
 	ctx->D = 0x10325476;
-	ctx->total = 0;
+	ctx->total64 = 0;
 }
 
 /* These are the four functions used in the four steps of the MD5 algorithm
@@ -48,8 +48,8 @@ void FAST_FUNC md5_begin(md5_ctx_t *ctx)
 
 #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s))))
 
-/* Hash a single block, 64 bytes long and 4-byte aligned. */
-static void md5_hash_block(md5_ctx_t *ctx)
+/* Hash a single block, 64 bytes long and 4-byte aligned */
+static void md5_process_block64(md5_ctx_t *ctx)
 {
 #if MD5_SIZE_VS_SPEED > 0
 	/* Before we start, one word to the strange constants.
@@ -95,7 +95,7 @@ static void md5_hash_block(md5_ctx_t *ctx)
 	};
 # endif
 #endif
-	const uint32_t *words = (const void*) ctx->buffer;
+	const uint32_t *words = (const void*) ctx->wbuffer;
 
 	uint32_t A = ctx->A;
 	uint32_t B = ctx->B;
@@ -354,29 +354,41 @@ static void md5_hash_block(md5_ctx_t *ctx)
 	ctx->D = D;
 }
 
-/* The first unused position in ctx->buffer: */
-#define BUFPOS(ctx) (((unsigned)ctx->total) & 63)
-
 /* Feed data through a temporary buffer to call md5_hash_aligned_block()
  * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
  * This function's internal buffer remembers previous data until it has 64
  * bytes worth to pass on.  Call md5_end() to flush this buffer. */
 void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 {
-#if 1
-	/* Tiny bit smaller code */
-	unsigned bufpos = BUFPOS(ctx);
+	unsigned bufpos = ctx->total64 & 63;
+	unsigned remaining;
 
 	/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
 	 * Here we only track the number of bytes.  */
-	ctx->total += len;
+	ctx->total64 += len;
+#if 0
+	remaining = 64 - bufpos;
 
+	/* Hash whole blocks */
+	while (len >= remaining) {
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
+		buffer = (const char *)buffer + remaining;
+		len -= remaining;
+		remaining = 64;
+		bufpos = 0;
+		md5_process_block64(ctx);
+	}
+
+	/* Save last, partial blosk */
+	memcpy(ctx->wbuffer + bufpos, buffer, len);
+#else
+	/* Tiny bit smaller code */
 	while (1) {
-		unsigned remaining = 64 - bufpos;
+		remaining = 64 - bufpos;
 		if (remaining > len)
 			remaining = len;
-		/* Copy data into aligned buffer. */
-		memcpy(ctx->buffer + bufpos, buffer, remaining);
+		/* Copy data into aligned buffer */
+		memcpy(ctx->wbuffer + bufpos, buffer, remaining);
 		len -= remaining;
 		buffer = (const char *)buffer + remaining;
 		bufpos += remaining;
@@ -384,30 +396,10 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
 		bufpos -= 64;
 		if (bufpos != 0)
 			break;
-		/* Buffer is filled up, process it. */
-		md5_hash_block(ctx);
+		/* Buffer is filled up, process it */
+		md5_process_block64(ctx);
 		/*bufpos = 0; - already is */
 	}
-#else
-	unsigned bufpos = BUFPOS(ctx);
-	unsigned add = 64 - bufpos;
-
-	/* RFC 1321 specifies the possible length of the file up to 2^64 bits.
-	 * Here we only track the number of bytes.  */
-	ctx->total += len;
-
-	/* Hash whole blocks */
-	while (len >= add) {
-		memcpy(ctx->buffer + bufpos, buffer, add);
-		buffer = (const char *)buffer + add;
-		len -= add;
-		add = 64;
-		bufpos = 0;
-		md5_hash_block(ctx);
-	}
-
-	/* Save last, partial blosk */
-	memcpy(ctx->buffer + bufpos, buffer, len);
 #endif
 }
 
@@ -418,25 +410,25 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
  */
 void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
 {
-	unsigned bufpos = BUFPOS(ctx);
+	unsigned bufpos = ctx->total64 & 63;
 	/* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
-	ctx->buffer[bufpos++] = 0x80;
+	ctx->wbuffer[bufpos++] = 0x80;
 
 	/* This loop iterates either once or twice, no more, no less */
 	while (1) {
 		unsigned remaining = 64 - bufpos;
-		memset(ctx->buffer + bufpos, 0, remaining);
+		memset(ctx->wbuffer + bufpos, 0, remaining);
 		/* Do we have enough space for the length count? */
 		if (remaining >= 8) {
 			/* Store the 64-bit counter of bits in the buffer in BE format */
-			uint64_t t = ctx->total << 3;
+			uint64_t t = ctx->total64 << 3;
 			unsigned i;
 			for (i = 0; i < 8; i++) {
-				ctx->buffer[56 + i] = t;
+				ctx->wbuffer[56 + i] = t;
 				t >>= 8;
 			}
 		}
-		md5_hash_block(ctx);
+		md5_process_block64(ctx);
 		if (remaining >= 8)
 			break;
 		bufpos = 0;
diff --git a/libbb/sha1.c b/libbb/sha1.c
index 3e61aff6d..d79291148 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -469,10 +469,10 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 
 	/* This loop iterates either once or twice, no more, no less */
 	while (1) {
-		unsigned pad = 64 - bufpos;
-		memset(ctx->wbuffer + bufpos, 0, pad);
+		unsigned remaining = 64 - bufpos;
+		memset(ctx->wbuffer + bufpos, 0, remaining);
 		/* Do we have enough space for the length count? */
-		if (pad >= 8) {
+		if (remaining >= 8) {
 			/* Store the 64-bit counter of bits in the buffer in BE format */
 			uint64_t t = ctx->total64 << 3;
 			t = hton64(t);
@@ -480,7 +480,7 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
 			*(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
 		}
 		ctx->process_block(ctx);
-		if (pad >= 8)
+		if (remaining >= 8)
 			break;
 		bufpos = 0;
 	}
@@ -503,9 +503,9 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 	ctx->wbuffer[bufpos++] = 0x80;
 
 	while (1) {
-		unsigned pad = 128 - bufpos;
-		memset(ctx->wbuffer + bufpos, 0, pad);
-		if (pad >= 16) {
+		unsigned remaining = 128 - bufpos;
+		memset(ctx->wbuffer + bufpos, 0, remaining);
+		if (remaining >= 16) {
 			/* Store the 128-bit counter of bits in the buffer in BE format */
 			uint64_t t;
 			t = ctx->total64[0] << 3;
@@ -516,7 +516,7 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
 			*(uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
 		}
 		sha512_process_block128(ctx);
-		if (pad >= 16)
+		if (remaining >= 16)
 			break;
 		bufpos = 0;
 	}
-- 
cgit v1.2.3-55-g6feb


From cfe114c4f3d4e1dfc00196d8df316874eaf2d2b8 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sun, 17 Oct 2010 11:38:44 +0200
Subject: md5: code shrink -5 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/md5.c | 75 +++++++++++++++++++++++++++++--------------------------------
 1 file changed, 35 insertions(+), 40 deletions(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index f5d083e3f..6001a9c8e 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -64,7 +64,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
 		/* round 2 */
 		0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
-		0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
+		0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
 		0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
 		0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
 		/* round 3 */
@@ -86,28 +86,21 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,	/* 3 */
 		0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9	/* 4 */
 	};
-# if MD5_SIZE_VS_SPEED > 1
-	static const char S_array[] ALIGN1 = {
-		7, 12, 17, 22,
-		5, 9, 14, 20,
-		4, 11, 16, 23,
-		6, 10, 15, 21
-	};
-# endif
 #endif
 	const uint32_t *words = (const void*) ctx->wbuffer;
-
 	uint32_t A = ctx->A;
 	uint32_t B = ctx->B;
 	uint32_t C = ctx->C;
 	uint32_t D = ctx->D;
 
-	uint32_t A_save = A;
-	uint32_t B_save = B;
-	uint32_t C_save = C;
-	uint32_t D_save = D;
+#if MD5_SIZE_VS_SPEED >= 2  /* 2 or 3 */
 
-#if MD5_SIZE_VS_SPEED > 1
+	static const char S_array[] ALIGN1 = {
+		7, 12, 17, 22,
+		5, 9, 14, 20,
+		4, 11, 16, 23,
+		6, 10, 15, 21
+	};
 	const uint32_t *pc;
 	const char *pp;
 	const char *ps;
@@ -119,7 +112,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		words[i] = SWAP_LE32(words[i]);
 # endif
 
-# if MD5_SIZE_VS_SPEED > 2
+# if MD5_SIZE_VS_SPEED == 3
 	pc = C_array;
 	pp = P_array;
 	ps = S_array - 4;
@@ -149,7 +142,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		C = B;
 		B = temp;
 	}
-# else /* MD5_SIZE_VS_SPEED == 2 */
+# else  /* MD5_SIZE_VS_SPEED == 2 */
 	pc = C_array;
 	pp = P_array;
 	ps = S_array;
@@ -194,8 +187,23 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		B = temp;
 	}
 # endif
+	/* Add checksum to the starting values */
+	ctx->A += A;
+	ctx->B += B;
+	ctx->C += C;
+	ctx->D += D;
 
-#else /* MD5_SIZE_VS_SPEED == 0 or 1 */
+#else  /* MD5_SIZE_VS_SPEED == 0 or 1 */
+
+	uint32_t A_save = A;
+	uint32_t B_save = B;
+	uint32_t C_save = C;
+	uint32_t D_save = D;
+# if MD5_SIZE_VS_SPEED == 1
+	const uint32_t *pc;
+	const char *pp;
+	int i;
+# endif
 
 	/* First round: using the given function, the context and a constant
 	   the next context is computed.  Because the algorithm's processing
@@ -212,13 +220,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		a += b; \
 	} while (0)
 
-# if MD5_SIZE_VS_SPEED == 1
-	const uint32_t *pc;
-	const char *pp;
-	int i;
-# endif
-
-	/* Round 1.  */
+	/* Round 1 */
 # if MD5_SIZE_VS_SPEED == 1
 	pc = C_array;
 	for (i = 0; i < 4; i++) {
@@ -258,7 +260,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		a += b; \
 	} while (0)
 
-	/* Round 2.  */
+	/* Round 2 */
 # if MD5_SIZE_VS_SPEED == 1
 	pp = P_array;
 	for (i = 0; i < 4; i++) {
@@ -286,7 +288,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 	OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
 # endif
 
-	/* Round 3.  */
+	/* Round 3 */
 # if MD5_SIZE_VS_SPEED == 1
 	for (i = 0; i < 4; i++) {
 		OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
@@ -313,7 +315,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 	OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
 # endif
 
-	/* Round 4.  */
+	/* Round 4 */
 # if MD5_SIZE_VS_SPEED == 1
 	for (i = 0; i < 4; i++) {
 		OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
@@ -339,19 +341,12 @@ static void md5_process_block64(md5_ctx_t *ctx)
 	OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
 	OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
 # endif
+	/* Add checksum to the starting values */
+	ctx->A = A_save + A;
+	ctx->B = B_save + B;
+	ctx->C = C_save + C;
+	ctx->D = D_save + D;
 #endif
-
-	/* Add the starting values of the context.  */
-	A += A_save;
-	B += B_save;
-	C += C_save;
-	D += D_save;
-
-	/* Put checksum in context given as argument.  */
-	ctx->A = A;
-	ctx->B = B;
-	ctx->C = C;
-	ctx->D = D;
 }
 
 /* Feed data through a temporary buffer to call md5_hash_aligned_block()
-- 
cgit v1.2.3-55-g6feb


From b8d02597e3dcea16b6aeda2d1aae11ca3812932a Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sun, 17 Oct 2010 23:01:32 +0200
Subject: md5: fix biuld failure on big-endian machines

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 libbb/md5.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'libbb')

diff --git a/libbb/md5.c b/libbb/md5.c
index 6001a9c8e..051c8ede4 100644
--- a/libbb/md5.c
+++ b/libbb/md5.c
@@ -87,7 +87,7 @@ static void md5_process_block64(md5_ctx_t *ctx)
 		0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9	/* 4 */
 	};
 #endif
-	const uint32_t *words = (const void*) ctx->wbuffer;
+	uint32_t *words = (void*) ctx->wbuffer;
 	uint32_t A = ctx->A;
 	uint32_t B = ctx->B;
 	uint32_t C = ctx->C;
-- 
cgit v1.2.3-55-g6feb


From c05387d5deca9e57c38077debc0f705199f32006 Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Mon, 18 Oct 2010 02:38:27 +0200
Subject: *: replace xopen3 with xopen where makes sense

function                                             old     new   delta
uniq_main                                            421     416      -5
sort_main                                            803     798      -5
patch_main                                          2051    2046      -5
cpio_main                                            547     542      -5

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 archival/cpio.c        | 2 +-
 coreutils/sort.c       | 2 +-
 coreutils/uniq.c       | 4 ++--
 editors/patch.c        | 2 +-
 editors/patch_toybox.c | 2 +-
 libbb/xfuncs_printf.c  | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

(limited to 'libbb')

diff --git a/archival/cpio.c b/archival/cpio.c
index 7cd8ee8a7..a2d74dc79 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -370,7 +370,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
 		if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */
 			bb_show_usage();
 		if (opt & CPIO_OPT_FILE) {
-			xmove_fd(xopen3(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666), STDOUT_FILENO);
+			xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
 		}
  dump:
 		return cpio_o();
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 4407b7105..716824321 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -412,7 +412,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
 #if ENABLE_FEATURE_SORT_BIG
 	/* Open output file _after_ we read all input ones */
 	if (option_mask32 & FLAG_o)
-		xmove_fd(xopen3(str_o, O_WRONLY, 0666), STDOUT_FILENO);
+		xmove_fd(xopen(str_o, O_WRONLY), STDOUT_FILENO);
 #endif
 	flag = (option_mask32 & FLAG_z) ? '\0' : '\n';
 	for (i = 0; i < linecount; i++)
diff --git a/coreutils/uniq.c b/coreutils/uniq.c
index f0364b9a1..358de7894 100644
--- a/coreutils/uniq.c
+++ b/coreutils/uniq.c
@@ -52,8 +52,8 @@ int uniq_main(int argc UNUSED_PARAM, char **argv)
 			if (output[0] != '-' || output[1]) {
 				// Won't work with "uniq - FILE" and closed stdin:
 				//close(STDOUT_FILENO);
-				//xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-				xmove_fd(xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666), STDOUT_FILENO);
+				//xopen(output, O_WRONLY | O_CREAT | O_TRUNC);
+				xmove_fd(xopen(output, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
 			}
 		}
 	}
diff --git a/editors/patch.c b/editors/patch.c
index 764f0f183..66a9474fe 100644
--- a/editors/patch.c
+++ b/editors/patch.c
@@ -591,7 +591,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 							xmkpath(name, -1);
 							*s = '/';
 						}
-						TT.filein = xopen3(name, O_CREAT|O_EXCL|O_RDWR, 0666);
+						TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR);
 					} else {
 						printf("patching file %s\n", name);
 						TT.filein = xopen(name, O_RDONLY);
diff --git a/editors/patch_toybox.c b/editors/patch_toybox.c
index 04bd98eea..a60bf070f 100644
--- a/editors/patch_toybox.c
+++ b/editors/patch_toybox.c
@@ -559,7 +559,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 							xmkpath(name, -1);
 							*s = '/';
 						}
-						TT.filein = xopen3(name, O_CREAT|O_EXCL|O_RDWR, 0666);
+						TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR);
 					} else {
 						printf("patching file %s\n", name);
 						TT.filein = xopen(name, O_RDWR);
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index c6db38d33..ba660a2db 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -134,7 +134,7 @@ int FAST_FUNC xopen3(const char *pathname, int flags, int mode)
 	return ret;
 }
 
-// Die if we can't open an existing file and return a fd.
+// Die if we can't open a file and return a fd.
 int FAST_FUNC xopen(const char *pathname, int flags)
 {
 	return xopen3(pathname, flags, 0666);
-- 
cgit v1.2.3-55-g6feb