diff --git a/libxcrypt-4.2.2-to_develop.patch b/libxcrypt-4.2.2-to_develop.patch deleted file mode 100644 index d42e74c..0000000 --- a/libxcrypt-4.2.2-to_develop.patch +++ /dev/null @@ -1,3945 +0,0 @@ -From 9bae80381beabc1b08b0fd89d2a4e6e15e3e5da0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Thu, 18 Oct 2018 21:24:10 +0200 -Subject: [PATCH 01/17] Bump tarball version to 4.2.3 and update NEWS. - ---- - NEWS | 2 ++ - configure.ac | 2 +- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/NEWS b/NEWS -index 5b2795e..ef7c244 100644 ---- a/NEWS -+++ b/NEWS -@@ -3,6 +3,8 @@ libxcrypt NEWS -- history of user-visible changes. - Please send bug reports, questions and suggestions to - . - -+Version 4.2.3 -+ - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. - -diff --git a/configure.ac b/configure.ac -index efbd2e7..3ba313c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1,7 +1,7 @@ - # Process this file with autoconf to produce a configure script. - m4_include([m4/zw_automodern.m4]) - AC_INIT([xcrypt], -- [4.2.2], -+ [4.2.3], - [https://github.com/besser82/libxcrypt/issues], - [libxcrypt], - [https://github.com/besser82/libxcrypt]) - -From ed11116c6e4b5b80ef8f6f57fe8db4aa3604a53b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Thu, 18 Oct 2018 22:23:19 +0200 -Subject: [PATCH 02/17] Add bootstrap script. - ---- - .travis.yml | 6 +++--- - NEWS | 1 + - bootstrap | 33 +++++++++++++++++++++++++++++++++ - 3 files changed, 37 insertions(+), 3 deletions(-) - create mode 100755 bootstrap - -diff --git a/.travis.yml b/.travis.yml -index 78a3f0a..acb186c 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -181,9 +181,9 @@ before_install: - - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y upgrade && i= && break || sleep 1; done; [ -z "$i" ]' - - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y swap coreutils-single coreutils && i= && break || sleep 1; done; [ -z "$i" ]' - - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y groups install buildsys-build && i= && break || sleep 1; done; [ -z "$i" ]' -- - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install libtool valgrind && i= && break || sleep 1; done; [ -z "$i" ]' -+ - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install git libtool valgrind && i= && break || sleep 1; done; [ -z "$i" ]' - - if [[ "$CC" == "clang" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install clang && i= && break || sleep 1; done; [ -z "$i" ]' ; fi -- - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install git lcov python3-pip && i= && break || sleep 1; done; [ -z "$i" ]' ; fi -+ - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y install lcov python3-pip && i= && break || sleep 1; done; [ -z "$i" ]' ; fi - - if [[ "$CODECOV" == "1" ]] ; then docker exec -t buildenv /bin/sh -c "pip3 install codecov" ; fi - - docker exec -t buildenv /bin/sh -c 'for i in `seq 0 99`; do dnf -y autoremove && i= && break || sleep 1; done; [ -z "$i" ]' - -@@ -201,7 +201,7 @@ script: - - export NPROCS="$((`nproc --all` * 2))" ; echo paralleism is $NPROCS - - if [[ "$CODECOV" == "1" ]] ; then export CFLAGS="-O0 -g --coverage" ; export CXXFLAGS="$CFLAGS" ; export LDFLAGS="--coverage" ; fi - - docker exec -t buildenv /bin/sh -c "cat /etc/redhat-release" -- - docker exec -t buildenv /bin/sh -c "cd /opt/libxcrypt && autoreconf -fiv -Wall -Werror" -+ - docker exec -t buildenv /bin/sh -c "cd /opt/libxcrypt && ./bootstrap" - - docker exec -t buildenv /bin/sh -c "cd /opt/libxcrypt && CFLAGS=\"$CFLAGS\" CXXFLAGS=\"$CXXFLAGS\" LDFLAGS=\"$LDFLAGS\" ./configure --prefix=/opt/libxcrypt --disable-silent-rules --enable-shared --enable-static $CONF" - - docker exec -t buildenv /bin/sh -c "make -C /opt/libxcrypt -j$NPROCS" - - docker exec -t buildenv /bin/sh -c "make -C /opt/libxcrypt install" -diff --git a/NEWS b/NEWS -index ef7c244..7847c86 100644 ---- a/NEWS -+++ b/NEWS -@@ -4,6 +4,7 @@ Please send bug reports, questions and suggestions to - . - - Version 4.2.3 -+* Add bootstrap script. - - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. -diff --git a/bootstrap b/bootstrap -new file mode 100755 -index 0000000..af6433a ---- /dev/null -+++ b/bootstrap -@@ -0,0 +1,33 @@ -+#!/bin/sh -+# -+# Copyright (C) 2018 Björn Esser -+# -+# Redistribution and use in source and binary forms, with or without -+# modification, are permitted. -+# -+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+# SUCH DAMAGE. -+ -+set -efu -+LANG=C -+ -+run_cmd() -+{ -+ echo "bootstrap: running: $@" -+ "$@" -+} -+ -+if [ -d .git ]; then -+ run_cmd git clean -dfX -+fi -+ -+run_cmd autoreconf -iv -Wall,error - -From a19bb7e1ae3e954b8852f50fd70ca496839989b5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Fri, 19 Oct 2018 00:01:16 +0200 -Subject: [PATCH 03/17] Recommend the bootstrap script over autoreconf. - ---- - NEWS | 3 ++- - README.md | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/NEWS b/NEWS -index 7847c86..c55a971 100644 ---- a/NEWS -+++ b/NEWS -@@ -4,7 +4,8 @@ Please send bug reports, questions and suggestions to - . - - Version 4.2.3 --* Add bootstrap script. -+* Add bootstrap script. If building from a Git checkout instead of a -+ tarball release, use './bootstrap' to create the configure script. - - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. -diff --git a/README.md b/README.md -index a32b1b1..102127a 100644 ---- a/README.md -+++ b/README.md -@@ -62,7 +62,7 @@ these things before building the software. - - Building from a Git checkout additionally requires the Autotools - suite: `autoconf`, `automake`, `libtool`, and `pkg-config`. --Run `autoreconf -i` at the top level of the source tree, and then -+Run `./bootstrap` at the top level of the source tree, and then - follow the instructions in `INSTALL` (which is created by that command). - - The oldest versions of Autotools components that are known to work - -From 4bb73c595925a4603393ff25751ada66921919d9 Mon Sep 17 00:00:00 2001 -From: Zack Weinberg -Date: Sat, 20 Oct 2018 12:36:02 -0400 -Subject: [PATCH 04/17] Revise the to-do list. - ---- - TODO | 57 +---------------------------- - TODO.md | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 110 insertions(+), 56 deletions(-) - mode change 100644 => 120000 TODO - create mode 100644 TODO.md - -diff --git a/TODO b/TODO -deleted file mode 100644 -index 66db86b..0000000 ---- a/TODO -+++ /dev/null -@@ -1,56 +0,0 @@ --to-do list for libxcrypt -------------------------- -- --* Near future: -- * Update all of the default cost parameters -- * relevant benchmarking at -- -- * the default used by `crypt_gensalt_*` for new hashes should be -- controllable independently from the default used if there is no -- rounds= annotation in a setting string -- * Make the crypt and crypt_gensalt static state thread-specific? -- * if allocated on first use, this would also shave 32kB of -- data segment off the shared library -- * Factor out all of the repetitive base64 code -- * get rid of the de/serialization code in crypt-bcrypt.c that -- still does dodgy things with type punning -- * Attempt to determine the copyright holders and intended licensing -- of the test suite -- * Moar tests -- * Make sure the symbol versioning macros work with all of the compilers -- that anyone needs (they use GCC extensions that clang also supports). -- --* Longer term: -- * Hash algorithms newer than bcrypt tend to want to allocate and -- scribble all over a large (tens of megabytes at a minimum) block -- of memory, to make brute force hard in a way that GPUs and ASICs -- can't easily accelerate. The existing API cannot handle this for -- three reasons: -- * `crypt_gensalt` only takes a single cost parameter, some -- algorithms have several -- * With everything except `crypt_ra`, all of the memory is -- allocated by the caller and there's no way for algorithms to say -- how much they need -- * There is no destructor function, even with `crypt_ra` - callers -- just pass the block to `free` -- -- So we need to invent a new API that allows for more variety in -- cost parameters and allocations. It could also make the "all the -- sensitive data, including stack scratch, is in crypt_data which we -- auto-erase" feature more robust by adding guard bands and calling -- mlock(). -- -- * Additional hashes to investigate adding: -- * scrypt -- * Argon2 -- * ...? -- -- * Support for "pepper" (an additional piece of information, _not_ -- stored in the password file, that you need to check a password) -- -- * Reading passphrases from the terminal is finicky and there are -- several competing, poorly portable, questionably sound library -- functions to do it (`getpass`, `readpassphrase`, etc) -- should we -- incorporate one? -- * If we do, should it know how to trigger the trusted-path -- password prompt in modern GUI environments? (probably) -diff --git a/TODO b/TODO -new file mode 120000 -index 0000000..cde952b ---- /dev/null -+++ b/TODO -@@ -0,0 +1 @@ -+TODO.md -\ No newline at end of file -diff --git a/TODO.md b/TODO.md -new file mode 100644 -index 0000000..30c0372 ---- /dev/null -+++ b/TODO.md -@@ -0,0 +1,109 @@ -+to-do list for libxcrypt -+------------------------ -+ -+This list is categorized but not in any kind of priority order. -+It was last updated 20 October 2018. -+ -+* Code cleanliness -+ * Find and remove any code that still does dodgy things with type punning -+ * Factor out all of the repetitive base64 code -+ * Factor out the multiple implementations of HMAC and PBKDF -+ -+* Testsuite improvements -+ * Line coverage is inadequate for `alg-yescrypt-common.c` and -+ `alg-yescrypt-opt.c` -+ * Investigate branch coverage -+ * Do some API fuzz testing and add missing cases to the testsuite -+ * Many of the `test-crypt-*.c` files repeat more or less the same -+ code with different data, consider merging them -+ -+* Portability -+ * Make sure the symbol versioning macros work with all of the -+ compilers that anyone needs (they use GCC extensions that clang -+ also supports). -+ * `alg-yescrypt-common.c` contains #ifdeffage for use of -+ `posix_memalign` that isn’t wired up to autoconf -+ * possibly this should just be removed; does anything have -+ `posix_memalign` but not `mmap`? it’s only a compile-time -+ fallback, not a runtime fallback -+ -+* Hardening -+ * bcrypt-like selftest/memory scribble for all hashing methods -+ * how do we know the memory scribble is doing its job? -+ * build out of the box with compiler hardening features turned on -+ * something bespoke for not having to write serialization and -+ deserialization logic for hash strings by hand, as this is -+ probably the most error-prone part of writing a hashing method -+ -+ * the most sensitive piece of data handled by this library is a -+ cleartext passphrase. OS may have trusted-path facilities for -+ prompting the user for a passphrase and feeding it to a KDF -+ without its ever being accessible in normal memory. investigate -+ whether we can use these. -+ -+* Additional hashing methods -+ * Argon2 -+ * ...? -+ -+* Runtime configurability (in progress on the [crypt.conf branch][]) -+ * allow installations to enable or disable specific hash methods -+ without rebuilding the library -+ * make the default cost parameter used by `crypt_gensalt_*` for new -+ hashes configurable -+ * update the compiled-in defaults used by `crypt_gensalt_*` (not the -+ defaults used when no explicit cost parameter is present in a -+ hash; those can’t be changed without breaking existing stored hashes) -+ * relevant benchmarking at -+ -+ * offer a way to tune cost parameters for a specific installation -+ * N.B. Solaris 11 has all of these features but our implementation will -+ probably not match them (they have a `crypt.conf` but it’s not the -+ same, and their `crypt_gensalt` is API-incompatible anyway). -+ -+[crypt.conf branch]: https://github.com/besser82/libxcrypt/tree/zack/crypt.conf -+ -+* Potential API enhancements: -+ -+ * Support for "pepper" (an additional piece of information, _not_ -+ stored in the password file, that you need to check a password) -+ -+ * Reading passphrases from the terminal is finicky and there are -+ several competing, poorly portable, questionably sound library -+ functions to do it (`getpass`, `readpassphrase`, etc) -- should we -+ incorporate one? -+ * If we do, should it know how to trigger the trusted-path -+ password prompt in modern GUI environments? (probably) -+ -+ * Make the crypt and crypt_gensalt static state thread-specific? -+ * Solaris 11 may have done this (its `crypt(3)` manpage describes -+ it as MT-Safe and I don’t see any other way they could have -+ accomplished that). -+ * if allocated on first use, this would also shave 32kB of -+ data segment off the shared library -+ * alternatively, add a global lock and *crash the program* if we -+ detect concurrent calls -+ -+ * Allow access to more of yescrypt’s tunable parameters and ROM -+ feature, in a way that’s generic enough that we could also use it -+ for e.g. Argon2’s tunable parameters -+ -+ * Other yescrypt-inspired features relevant to using this library to -+ back a “dedicated authentication service,” e.g. preallocation of -+ large blocks of scratch memory -+ * the main obstacles here are that `struct crypt_data` has a fixed -+ size which is either too big or too small depending how you look -+ at it, and no destructor function -+ -+* Permissive relicensing, to encourage use beyond the GNU ecosystem? -+ * Replace remaining (L)GPLed crypto primitives (MD5, SHA512) with -+ permissively licensed equivalents (e.g. from Openwall) -+ * Replace crypt-md5.c with original md5crypt from FreeBSD? -+ * Other files subject to the (L)GPL are crypt.c, crypt-static.c, -+ crypt-gensalt-static.c, crypt-obsolete.h, crypt-port.h, -+ crypt-private.h, test-badsalt.c. It is not clear to me how much -+ material originally assigned to the FSF remains in these files. -+ Several of them are API definitions and trivial wrappers that -+ could not be meaningfully changed without breaking them (so are -+ arguably uncopyrightable). -+ * Most of the test suite lacks any license or even authorship -+ information. We would have to track down the original authors. - -From 9787b0be83a077c8c1a4e9b460b6b6e3698002d4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 21 Oct 2018 12:18:25 +0200 -Subject: [PATCH 05/17] Generate included header files before any other target. - -If we use a dummy target that depends on targets generating -commonly used header files and that creates an empty file, -which is included in the Makefile later, the header files are -guaranteed to be generated before any other target in the same -Makefile. ---- - .gitignore | 1 + - Makefile.am | 16 +++++++++------- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/.gitignore b/.gitignore -index 1e9e605..e0b13cf 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -1,6 +1,7 @@ - # http://www.gnu.org/software/automake - - /Makefile -+/Makefile.deps - /Makefile.in - /.deps/ - /.libs/ -diff --git a/Makefile.am b/Makefile.am -index 2cb07ca..acab882 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -71,13 +71,19 @@ libcrypt_la_CPPFLAGS = $(AM_CPPFLAGS) -DIN_LIBCRYPT - - CONFIG_STATUS_DEPENDENCIES = libcrypt.minver - EXTRA_libcrypt_la_DEPENDENCIES = libcrypt.map --CLEANFILES = libcrypt.map libcrypt.map.T \ -+CLEANFILES = Makefile.deps.T Makefile.deps \ -+ libcrypt.map libcrypt.map.T \ - crypt-symbol-vers.h crypt-symbol-vers.h.T \ - crypt-hashes.h crypt-hashes.h.T \ - crypt.h crypt.h.T - - DISTCLEANFILES = .deps/*.Plo - -+# Empty target to have needed headers pre-generated before any other target. -+Makefile.deps: crypt-hashes.h crypt-symbol-vers.h -+ $(AM_V_GEN)LC_ALL=C echo "# Deps" > Makefile.deps.T -+ $(AM_V_at)mv -f Makefile.deps.T Makefile.deps -+ - libcrypt.map: libcrypt.map.in gen-map.awk Makefile - $(AM_V_GEN)LC_ALL=C $(AWK) \ - -v SYMVER_MIN=$(SYMVER_MIN) \ -@@ -230,12 +236,8 @@ endif - - # Every object file depends on crypt-symbol-vers.h and crypt-hashes.h, - # which are generated files, so automatic dependency generation is not --# sufficient. Most of the test programs depend on either libcrypt.la --# or one of its components, so they do not need an explicit dependency --# (after the first *successful* build, automatic dependency generation --# will reveal the direct dependency) but a few don't. --$(libcrypt_la_OBJECTS): crypt-symbol-vers.h crypt-hashes.h --$(test_byteorder_OBJECTS): crypt-symbol-vers.h crypt-hashes.h -+# sufficient. -+include $(builddir)/Makefile.deps - - # Add additional targets - .PHONY: $(phony_targets) - -From d32b170da3d4b65e9b23bb1c9a50e027ec090c5a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 21 Oct 2018 12:53:13 +0200 -Subject: [PATCH 06/17] Include crypt.h from crypt-port.h. - -Since we have a guaranteed way to make sure all generated header -files are always present before any object file is compiled, we -can drop crypt-base.h and include the local version of crypt.h -through crypt-port.h. ---- - .gitignore | 2 +- - LICENSING | 2 +- - Makefile.am | 10 +++++----- - configure.ac | 2 +- - crypt-gensalt-static.c | 1 - - crypt-obsolete.h | 1 - - crypt-port.h | 6 ++++-- - crypt-private.h | 1 - - crypt-static.c | 1 - - crypt-base.h.in => crypt.h.in.in | 0 - gen-crypt-h.awk | 2 +- - test-crypt-bcrypt.c | 1 - - test-crypt-des.c | 1 - - test-crypt-md5.c | 1 - - test-crypt-nthash.c | 1 - - test-crypt-pbkdf1-sha1.c | 1 - - test-crypt-scrypt.c | 1 - - test-crypt-sha256.c | 1 - - test-crypt-sha512.c | 1 - - test-crypt-sunmd5.c | 1 - - test-crypt-yescrypt.c | 1 - - test-des-obsolete.c | 1 - - test-des-obsolete_r.c | 1 - - test-gensalt.c | 1 - - 24 files changed, 13 insertions(+), 28 deletions(-) - rename crypt-base.h.in => crypt.h.in.in (100%) - -diff --git a/.gitignore b/.gitignore -index e0b13cf..e46e4c2 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -19,7 +19,7 @@ - /config.status - /m4/config.sub - /configure --/crypt-base.h -+/crypt.h.in - /m4/depcomp - /m4/install-sh - /libtool -diff --git a/LICENSING b/LICENSING -index 17ae41e..bf0c514 100644 ---- a/LICENSING -+++ b/LICENSING -@@ -12,7 +12,7 @@ source tree. For specific licensing terms consult the files themselves. - crypt.c, crypt-static.c, crypt-gensalt-static.c, crypt-port.h - - * Copyright Free Software Foundation, Inc.; LGPL (v2.1 or later): -- crypt-base.h, crypt-obsolete.h, crypt-private.h -+ crypt.h, crypt-obsolete.h, crypt-private.h - alg-md5.h, alg-md5.c, crypt-md5.c, - alg-sha512.h, alg-sha512.c, - test-crypt-badsalt.c, test-crypt-nonnull.c -diff --git a/Makefile.am b/Makefile.am -index acab882..498c48f 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -14,7 +14,7 @@ TEST_EXTENSIONS = .sh - - EXTRA_DIST = \ - LICENSING THANKS \ -- crypt-base.h.in libcrypt.map.in libcrypt.minver \ -+ crypt.h.in.in libcrypt.map.in libcrypt.minver \ - gen-map.awk gen-vers.awk gen-crypt-h.awk \ - gen-hashes.awk sel-hashes.awk hashes.lst - -@@ -24,7 +24,7 @@ notrans_dist_man3_MANS = \ - notrans_dist_man5_MANS = crypt.5 - - nodist_include_HEADERS = crypt.h --nodist_noinst_HEADERS = crypt-hashes.h crypt-base.h -+nodist_noinst_HEADERS = crypt-hashes.h - noinst_HEADERS = \ - alg-des.h alg-hmac-sha1.h alg-md4.h alg-md5.h \ - alg-sha1.h alg-sha256.h alg-sha512.h \ -@@ -80,7 +80,7 @@ CLEANFILES = Makefile.deps.T Makefile.deps \ - DISTCLEANFILES = .deps/*.Plo - - # Empty target to have needed headers pre-generated before any other target. --Makefile.deps: crypt-hashes.h crypt-symbol-vers.h -+Makefile.deps: crypt.h - $(AM_V_GEN)LC_ALL=C echo "# Deps" > Makefile.deps.T - $(AM_V_at)mv -f Makefile.deps.T Makefile.deps - -@@ -101,9 +101,9 @@ crypt-symbol-vers.h: libcrypt.map.in gen-vers.awk Makefile - $(srcdir)/libcrypt.map.in > crypt-symbol-vers.h.T - $(AM_V_at)mv -f crypt-symbol-vers.h.T crypt-symbol-vers.h - --crypt.h: crypt-base.h gen-crypt-h.awk config.h -+crypt.h: crypt.h.in crypt-hashes.h crypt-symbol-vers.h gen-crypt-h.awk config.h - $(AM_V_GEN)LC_ALL=C $(AWK) \ -- -f $(srcdir)/gen-crypt-h.awk config.h $(builddir)/crypt-base.h \ -+ -f $(srcdir)/gen-crypt-h.awk config.h $(builddir)/crypt.h.in \ - > crypt.h.T - $(AM_V_at)mv -f crypt.h.T crypt.h - -diff --git a/configure.ac b/configure.ac -index 3ba313c..5da8aa8 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -11,8 +11,8 @@ AC_CONFIG_SRCDIR([crypt.c]) - AC_CONFIG_HEADERS([config.h]) - AC_CONFIG_FILES([ - Makefile -+ crypt.h.in - libxcrypt.pc -- crypt-base.h - ]) - AM_INIT_AUTOMAKE - -diff --git a/crypt-gensalt-static.c b/crypt-gensalt-static.c -index 14f271e..590ee83 100644 ---- a/crypt-gensalt-static.c -+++ b/crypt-gensalt-static.c -@@ -15,7 +15,6 @@ - . */ - - #include "crypt-port.h" --#include "crypt-base.h" - - /* The functions that use global state objects are isolated in their - own files so that a statically-linked program that doesn't use them -diff --git a/crypt-obsolete.h b/crypt-obsolete.h -index d1acdea..4ecd969 100644 ---- a/crypt-obsolete.h -+++ b/crypt-obsolete.h -@@ -19,7 +19,6 @@ - #ifndef _CRYPT_OBSOLETE_H - #define _CRYPT_OBSOLETE_H 1 - --#include "crypt-base.h" - - /* These functions are obsolete and should never be used, but we have to - keep providing them for binary backward compatibility. */ -diff --git a/crypt-port.h b/crypt-port.h -index f139efa..5f4d55f 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -44,8 +44,8 @@ - #endif - - /* While actually compiling the library, suppress the __nonnull tags -- on the functions in crypt-base.h, so that internal checks for NULL -- are not deleted by the compiler. */ -+ on the functions in crypt.h, so that internal checks for NULL are -+ not deleted by the compiler. */ - #undef __nonnull - #define __nonnull(param) /* nothing */ - -@@ -292,4 +292,6 @@ _xcrypt_strcpy_or_abort (void *dst, const size_t d_size, - #define libcperciva_SHA256_Buf _crypt_SHA256_Buf - #endif - -+#include "crypt.h" -+ - #endif /* crypt-port.h */ -diff --git a/crypt-private.h b/crypt-private.h -index 5e18030..306879d 100644 ---- a/crypt-private.h -+++ b/crypt-private.h -@@ -20,7 +20,6 @@ - #ifndef _CRYPT_PRIVATE_H - #define _CRYPT_PRIVATE_H 1 - --#include "crypt-base.h" - - /* Utility functions */ - -diff --git a/crypt-static.c b/crypt-static.c -index fb9a953..d7598d1 100644 ---- a/crypt-static.c -+++ b/crypt-static.c -@@ -15,7 +15,6 @@ - . */ - - #include "crypt-port.h" --#include "crypt-base.h" - - /* The functions that use global state objects are isolated in their - own files so that a statically-linked program that doesn't use them -diff --git a/crypt-base.h.in b/crypt.h.in.in -similarity index 100% -rename from crypt-base.h.in -rename to crypt.h.in.in -diff --git a/gen-crypt-h.awk b/gen-crypt-h.awk -index 70fc5fa..8b3f4f5 100644 ---- a/gen-crypt-h.awk -+++ b/gen-crypt-h.awk -@@ -1,4 +1,4 @@ --# Generation of crypt.h from crypt-base.h and config.h. -+# Generation of crypt.h from crypt.h.in and config.h. - # - # Written by Zack Weinberg in 2017. - # To the extent possible under law, Zack Weinberg has waived all -diff --git a/test-crypt-bcrypt.c b/test-crypt-bcrypt.c -index bf149b4..5cf90c1 100644 ---- a/test-crypt-bcrypt.c -+++ b/test-crypt-bcrypt.c -@@ -15,7 +15,6 @@ - */ - - #include "crypt-port.h" --#include "crypt-base.h" - - #include - #include -diff --git a/test-crypt-des.c b/test-crypt-des.c -index 1b5463e..f01fee7 100644 ---- a/test-crypt-des.c -+++ b/test-crypt-des.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-crypt-md5.c b/test-crypt-md5.c -index 3035c39..d42b529 100644 ---- a/test-crypt-md5.c -+++ b/test-crypt-md5.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #if INCLUDE_md5 - -diff --git a/test-crypt-nthash.c b/test-crypt-nthash.c -index 9bf7d28..b344d86 100644 ---- a/test-crypt-nthash.c -+++ b/test-crypt-nthash.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-crypt-pbkdf1-sha1.c b/test-crypt-pbkdf1-sha1.c -index 677e5bf..7a0c826 100644 ---- a/test-crypt-pbkdf1-sha1.c -+++ b/test-crypt-pbkdf1-sha1.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - #include -diff --git a/test-crypt-scrypt.c b/test-crypt-scrypt.c -index df64774..0cf8da3 100644 ---- a/test-crypt-scrypt.c -+++ b/test-crypt-scrypt.c -@@ -18,7 +18,6 @@ - */ - - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-crypt-sha256.c b/test-crypt-sha256.c -index 05135ff..9331d14 100644 ---- a/test-crypt-sha256.c -+++ b/test-crypt-sha256.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-crypt-sha512.c b/test-crypt-sha512.c -index bef271b..88c5643 100644 ---- a/test-crypt-sha512.c -+++ b/test-crypt-sha512.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-crypt-sunmd5.c b/test-crypt-sunmd5.c -index d0d85e3..88e8ecf 100644 ---- a/test-crypt-sunmd5.c -+++ b/test-crypt-sunmd5.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - #include -diff --git a/test-crypt-yescrypt.c b/test-crypt-yescrypt.c -index da6b694..a635f94 100644 ---- a/test-crypt-yescrypt.c -+++ b/test-crypt-yescrypt.c -@@ -17,7 +17,6 @@ - */ - - #include "crypt-port.h" --#include "crypt-base.h" - - #include - -diff --git a/test-des-obsolete.c b/test-des-obsolete.c -index d5e3cc0..4588c75 100644 ---- a/test-des-obsolete.c -+++ b/test-des-obsolete.c -@@ -7,7 +7,6 @@ - */ - - #include "crypt-port.h" --#include "crypt-base.h" - #include "crypt-obsolete.h" - #include "test-des-cases.h" - -diff --git a/test-des-obsolete_r.c b/test-des-obsolete_r.c -index d635b2a..9efd0fb 100644 ---- a/test-des-obsolete_r.c -+++ b/test-des-obsolete_r.c -@@ -7,7 +7,6 @@ - */ - - #include "crypt-port.h" --#include "crypt-base.h" - #include "crypt-obsolete.h" - #include "test-des-cases.h" - -diff --git a/test-gensalt.c b/test-gensalt.c -index a6d3621..40fe66c 100644 ---- a/test-gensalt.c -+++ b/test-gensalt.c -@@ -1,5 +1,4 @@ - #include "crypt-port.h" --#include "crypt-base.h" - - #include - #include - -From a5f8acd51acb267d989ea3375ab17e29a0857059 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 21 Oct 2018 13:06:59 +0200 -Subject: [PATCH 07/17] Add crypt-symbol-vers.h to nodist_noinst_HEADERS. - ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 498c48f..a09e6a4 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -24,7 +24,7 @@ notrans_dist_man3_MANS = \ - notrans_dist_man5_MANS = crypt.5 - - nodist_include_HEADERS = crypt.h --nodist_noinst_HEADERS = crypt-hashes.h -+nodist_noinst_HEADERS = crypt-hashes.h crypt-symbol-vers.h - noinst_HEADERS = \ - alg-des.h alg-hmac-sha1.h alg-md4.h alg-md5.h \ - alg-sha1.h alg-sha256.h alg-sha512.h \ - -From 6adbd465a6003cf856e4c9debe0e6049746c685a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Sun, 21 Oct 2018 16:11:30 +0200 -Subject: [PATCH 08/17] Add gen-des-tables to noinst_PROGRAMS. - ---- - .gitignore | 1 + - Makefile.am | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/.gitignore b/.gitignore -index e46e4c2..8aead50 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -48,6 +48,7 @@ - /crypt-hashes.h - /crypt-symbol-vers.h - /libcrypt.map -+/gen-des-tables - /test-alg-des - /test-alg-hmac-sha1 - /test-alg-md4 -diff --git a/Makefile.am b/Makefile.am -index a09e6a4..e7d5c6d 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -31,6 +31,8 @@ noinst_HEADERS = \ - alg-yescrypt.h alg-yescrypt-sysendian.h byteorder.h \ - crypt-obsolete.h crypt-private.h crypt-port.h test-des-cases.h - -+noinst_PROGRAMS = gen-des-tables -+ - lib_LTLIBRARIES = libcrypt.la - libcrypt_la_SOURCES = \ - alg-des.c alg-des-tables.c alg-hmac-sha1.c alg-md4.c alg-md5.c \ - -From 323e5e097f643641f41f24969227b073470e186e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 22 Oct 2018 13:08:36 +0200 -Subject: [PATCH 09/17] Use sha512 implementation from Colin Percival. - -Thus we now have a sha512 implementation under the BSD license. ---- - LICENSING | 4 +- - NEWS | 2 + - TODO.md | 2 +- - alg-sha512.c | 566 +++++++++++++++++++++------------------ - alg-sha512.h | 121 +++++---- - alg-yescrypt-sysendian.h | 12 + - crypt-port.h | 7 +- - crypt-sha512.c | 56 ++-- - test-alg-sha512.c | 23 +- - 9 files changed, 441 insertions(+), 352 deletions(-) - -diff --git a/LICENSING b/LICENSING -index bf0c514..31f704c 100644 ---- a/LICENSING -+++ b/LICENSING -@@ -14,7 +14,6 @@ source tree. For specific licensing terms consult the files themselves. - * Copyright Free Software Foundation, Inc.; LGPL (v2.1 or later): - crypt.h, crypt-obsolete.h, crypt-private.h - alg-md5.h, alg-md5.c, crypt-md5.c, -- alg-sha512.h, alg-sha512.c, - test-crypt-badsalt.c, test-crypt-nonnull.c - - * Copyright David Burren et al.; 3-clause BSD: -@@ -34,6 +33,9 @@ source tree. For specific licensing terms consult the files themselves. - alg-sha256.c, alg-sha256.h, alg-yescrypt.h, alg-yescrypt-opt.c, - alg-yescrypt-sysendian.h - -+ * Copyright Colin Percival; 2-clause BSD: -+ alg-sha512.h, alg-sha512.c -+ - * Copyright Alexander Peslyak, Björn Esser; 0-clause BSD: - crypt-scrypt.c - -diff --git a/NEWS b/NEWS -index c55a971..c4b04da 100644 ---- a/NEWS -+++ b/NEWS -@@ -6,6 +6,8 @@ Please send bug reports, questions and suggestions to - Version 4.2.3 - * Add bootstrap script. If building from a Git checkout instead of a - tarball release, use './bootstrap' to create the configure script. -+* Use sha512 implementation from Colin Percival. Thus we now have a -+ sha512 implementation under the BSD license. - - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. -diff --git a/TODO.md b/TODO.md -index 30c0372..c4e2799 100644 ---- a/TODO.md -+++ b/TODO.md -@@ -95,7 +95,7 @@ It was last updated 20 October 2018. - at it, and no destructor function - - * Permissive relicensing, to encourage use beyond the GNU ecosystem? -- * Replace remaining (L)GPLed crypto primitives (MD5, SHA512) with -+ * Replace remaining (L)GPLed crypto primitives (MD5) with - permissively licensed equivalents (e.g. from Openwall) - * Replace crypt-md5.c with original md5crypt from FreeBSD? - * Other files subject to the (L)GPL are crypt.c, crypt-static.c, -diff --git a/alg-sha512.c b/alg-sha512.c -index 60c1877..0d24301 100644 ---- a/alg-sha512.c -+++ b/alg-sha512.c -@@ -1,289 +1,335 @@ --/* Functions to compute SHA512 message digest of files or memory blocks. -- according to the definition of SHA512 in FIPS 180-2. -- Copyright (C) 2007-2017 Free Software Foundation, Inc. -+/*- -+ * Copyright 2005 Colin Percival -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ - -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation; either version 2.1 of -- the License, or (at your option) any later version. -+#include "crypt-port.h" - -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -+#if INCLUDE_sha512 - -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, see -- . */ -+#include "alg-sha512.h" -+#include "alg-yescrypt-sysendian.h" - --/* Written by Ulrich Drepper , 2007. */ -+#if IS_BIGENDIAN -+/* Copy a vector of big-endian uint64_t into a vector of bytes */ -+#define be64enc_vect(dst, src, len) \ -+ memcpy((void *)dst, (const void *)src, (size_t)len) - --#include "crypt-port.h" --#include "alg-sha512.h" --#include "byteorder.h" -+/* Copy a vector of bytes into a vector of big-endian uint64_t */ -+#define be64dec_vect(dst, src, len) \ -+ memcpy((void *)dst, (const void *)src, (size_t)len) - --#if INCLUDE_sha512 -+#else /* IS_BIGENDIAN */ - --/* Constants for SHA512 from FIPS 180-2:4.2.3. */ --static const uint64_t K[80] = -+/* -+ * Encode a length len/4 vector of (uint64_t) into a length len vector of -+ * (unsigned char) in big-endian form. Assumes len is a multiple of 8. -+ */ -+static void -+be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len) - { -- UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), -- UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), -- UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), -- UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), -- UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), -- UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), -- UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), -- UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), -- UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), -- UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), -- UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), -- UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), -- UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), -- UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), -- UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), -- UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), -- UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), -- UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), -- UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), -- UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), -- UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), -- UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), -- UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), -- UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), -- UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), -- UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), -- UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), -- UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), -- UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), -- UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), -- UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), -- UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), -- UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), -- UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), -- UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), -- UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), -- UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), -- UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), -- UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), -- UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817) --}; -+ size_t i; - -+ for (i = 0; i < len / 8; i++) -+ be64enc(dst + i * 8, src[i]); -+} - --/* Process LEN bytes of BUFFER, accumulating context into CTX. -- It is assumed that LEN % 128 == 0. */ -+/* -+ * Decode a big-endian length len vector of (unsigned char) into a length -+ * len/4 vector of (uint64_t). Assumes len is a multiple of 8. -+ */ - static void --sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) -+be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len) - { -- unsigned int t; -- const unsigned char *p = buffer; -- size_t nwords = len / sizeof (uint64_t); -- uint64_t a = ctx->H[0]; -- uint64_t b = ctx->H[1]; -- uint64_t c = ctx->H[2]; -- uint64_t d = ctx->H[3]; -- uint64_t e = ctx->H[4]; -- uint64_t f = ctx->H[5]; -- uint64_t g = ctx->H[6]; -- uint64_t h = ctx->H[7]; -- -- /* First increment the byte count. FIPS 180-2 specifies the possible -- length of the file up to 2^128 bits. Here we only compute the -- number of bytes. Do a double word increment. */ -- ctx->total[0] += len; -- if (ctx->total[0] < len) -- ++ctx->total[1]; -- -- /* Process all bytes in the buffer with 128 bytes in each round of -- the loop. */ -- while (nwords > 0) -- { -- uint64_t W[80]; -- uint64_t a_save = a; -- uint64_t b_save = b; -- uint64_t c_save = c; -- uint64_t d_save = d; -- uint64_t e_save = e; -- uint64_t f_save = f; -- uint64_t g_save = g; -- uint64_t h_save = h; -- -- /* Operators defined in FIPS 180-2:4.1.2. */ --#define Ch(x, y, z) ((x & y) ^ (~x & z)) --#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) --#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) --#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) --#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) --#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) -- -- /* It is unfortunate that C does not provide an operator for -- cyclic rotation. Hope the C compiler is smart enough. */ --#define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) -- -- /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ -- for (t = 0; t < 16; ++t) -- { -- W[t] = be64_to_cpu (p); -- p += 8; -- } -- for (t = 16; t < 80; ++t) -- W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; -- -- /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ -- for (t = 0; t < 80; ++t) -- { -- uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; -- uint64_t T2 = S0 (a) + Maj (a, b, c); -- h = g; -- g = f; -- f = e; -- e = d + T1; -- d = c; -- c = b; -- b = a; -- a = T1 + T2; -- } -- -- /* Add the starting values of the context according to FIPS 180-2:6.3.2 -- step 4. */ -- a += a_save; -- b += b_save; -- c += c_save; -- d += d_save; -- e += e_save; -- f += f_save; -- g += g_save; -- h += h_save; -- -- /* Prepare for the next round. */ -- nwords -= 16; -- } -- -- /* Put checksum in context given as argument. */ -- ctx->H[0] = a; -- ctx->H[1] = b; -- ctx->H[2] = c; -- ctx->H[3] = d; -- ctx->H[4] = e; -- ctx->H[5] = f; -- ctx->H[6] = g; -- ctx->H[7] = h; -+ size_t i; -+ -+ for (i = 0; i < len / 8; i++) -+ dst[i] = be64dec(src + i * 8); - } - -+#endif /* IS_BIGENDIAN */ -+ -+/* Elementary functions used by SHA512 */ -+#define Ch(x, y, z) ((x & (y ^ z)) ^ z) -+#define Maj(x, y, z) ((x & (y | z)) | (y & z)) -+#define SHR(x, n) (x >> n) -+#define ROTR(x, n) ((x >> n) | (x << (64 - n))) -+#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) -+#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) -+#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) -+#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) -+ -+/* SHA512 round function */ -+#define RND(a, b, c, d, e, f, g, h, k) \ -+ t0 = h + S1(e) + Ch(e, f, g) + k; \ -+ t1 = S0(a) + Maj(a, b, c); \ -+ d += t0; \ -+ h = t0 + t1; -+ -+/* Adjusted round function for rotating state */ -+#define RNDr(S, W, i, k) \ -+ RND(S[(80 - i) % 8], S[(81 - i) % 8], \ -+ S[(82 - i) % 8], S[(83 - i) % 8], \ -+ S[(84 - i) % 8], S[(85 - i) % 8], \ -+ S[(86 - i) % 8], S[(87 - i) % 8], \ -+ W[i] + k) -+ -+/* -+ * SHA512 block compression function. The 512-bit state is transformed via -+ * the 512-bit input block to produce a new state. -+ */ -+static void -+SHA512_Transform(uint64_t * state, const unsigned char block[128]) -+{ -+ uint64_t W[80]; -+ uint64_t S[8]; -+ uint64_t t0, t1; -+ int i; -+ -+ /* 1. Prepare message schedule W. */ -+ be64dec_vect(W, block, 128); -+ for (i = 16; i < 80; i++) -+ W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; -+ -+ /* 2. Initialize working variables. */ -+ memcpy(S, state, 64); -+ -+ /* 3. Mix. */ -+ RNDr(S, W, 0, 0x428a2f98d728ae22ULL); -+ RNDr(S, W, 1, 0x7137449123ef65cdULL); -+ RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL); -+ RNDr(S, W, 3, 0xe9b5dba58189dbbcULL); -+ RNDr(S, W, 4, 0x3956c25bf348b538ULL); -+ RNDr(S, W, 5, 0x59f111f1b605d019ULL); -+ RNDr(S, W, 6, 0x923f82a4af194f9bULL); -+ RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL); -+ RNDr(S, W, 8, 0xd807aa98a3030242ULL); -+ RNDr(S, W, 9, 0x12835b0145706fbeULL); -+ RNDr(S, W, 10, 0x243185be4ee4b28cULL); -+ RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL); -+ RNDr(S, W, 12, 0x72be5d74f27b896fULL); -+ RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL); -+ RNDr(S, W, 14, 0x9bdc06a725c71235ULL); -+ RNDr(S, W, 15, 0xc19bf174cf692694ULL); -+ RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL); -+ RNDr(S, W, 17, 0xefbe4786384f25e3ULL); -+ RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL); -+ RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL); -+ RNDr(S, W, 20, 0x2de92c6f592b0275ULL); -+ RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL); -+ RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL); -+ RNDr(S, W, 23, 0x76f988da831153b5ULL); -+ RNDr(S, W, 24, 0x983e5152ee66dfabULL); -+ RNDr(S, W, 25, 0xa831c66d2db43210ULL); -+ RNDr(S, W, 26, 0xb00327c898fb213fULL); -+ RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL); -+ RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL); -+ RNDr(S, W, 29, 0xd5a79147930aa725ULL); -+ RNDr(S, W, 30, 0x06ca6351e003826fULL); -+ RNDr(S, W, 31, 0x142929670a0e6e70ULL); -+ RNDr(S, W, 32, 0x27b70a8546d22ffcULL); -+ RNDr(S, W, 33, 0x2e1b21385c26c926ULL); -+ RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL); -+ RNDr(S, W, 35, 0x53380d139d95b3dfULL); -+ RNDr(S, W, 36, 0x650a73548baf63deULL); -+ RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL); -+ RNDr(S, W, 38, 0x81c2c92e47edaee6ULL); -+ RNDr(S, W, 39, 0x92722c851482353bULL); -+ RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL); -+ RNDr(S, W, 41, 0xa81a664bbc423001ULL); -+ RNDr(S, W, 42, 0xc24b8b70d0f89791ULL); -+ RNDr(S, W, 43, 0xc76c51a30654be30ULL); -+ RNDr(S, W, 44, 0xd192e819d6ef5218ULL); -+ RNDr(S, W, 45, 0xd69906245565a910ULL); -+ RNDr(S, W, 46, 0xf40e35855771202aULL); -+ RNDr(S, W, 47, 0x106aa07032bbd1b8ULL); -+ RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL); -+ RNDr(S, W, 49, 0x1e376c085141ab53ULL); -+ RNDr(S, W, 50, 0x2748774cdf8eeb99ULL); -+ RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL); -+ RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL); -+ RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL); -+ RNDr(S, W, 54, 0x5b9cca4f7763e373ULL); -+ RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL); -+ RNDr(S, W, 56, 0x748f82ee5defb2fcULL); -+ RNDr(S, W, 57, 0x78a5636f43172f60ULL); -+ RNDr(S, W, 58, 0x84c87814a1f0ab72ULL); -+ RNDr(S, W, 59, 0x8cc702081a6439ecULL); -+ RNDr(S, W, 60, 0x90befffa23631e28ULL); -+ RNDr(S, W, 61, 0xa4506cebde82bde9ULL); -+ RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL); -+ RNDr(S, W, 63, 0xc67178f2e372532bULL); -+ RNDr(S, W, 64, 0xca273eceea26619cULL); -+ RNDr(S, W, 65, 0xd186b8c721c0c207ULL); -+ RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL); -+ RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL); -+ RNDr(S, W, 68, 0x06f067aa72176fbaULL); -+ RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL); -+ RNDr(S, W, 70, 0x113f9804bef90daeULL); -+ RNDr(S, W, 71, 0x1b710b35131c471bULL); -+ RNDr(S, W, 72, 0x28db77f523047d84ULL); -+ RNDr(S, W, 73, 0x32caab7b40c72493ULL); -+ RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL); -+ RNDr(S, W, 75, 0x431d67c49c100d4cULL); -+ RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL); -+ RNDr(S, W, 77, 0x597f299cfc657e2aULL); -+ RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL); -+ RNDr(S, W, 79, 0x6c44198c4a475817ULL); -+ -+ /* 4. Mix local working variables into global state */ -+ for (i = 0; i < 8; i++) -+ state[i] += S[i]; -+} - --/* Initialize structure containing state of computation. -- (FIPS 180-2:5.3.3) */ --void --sha512_init_ctx (struct sha512_ctx *ctx) -+static unsigned char PAD[128] = { -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+}; -+ -+/* Add padding and terminating bit-count. */ -+static void -+SHA512_Pad(SHA512_CTX * ctx) - { -- ctx->H[0] = UINT64_C (0x6a09e667f3bcc908); -- ctx->H[1] = UINT64_C (0xbb67ae8584caa73b); -- ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b); -- ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1); -- ctx->H[4] = UINT64_C (0x510e527fade682d1); -- ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f); -- ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b); -- ctx->H[7] = UINT64_C (0x5be0cd19137e2179); -- -- ctx->total[0] = ctx->total[1] = 0; -- ctx->buflen = 0; -+ unsigned char len[16]; -+ uint64_t r, plen; -+ -+ /* -+ * Convert length to a vector of bytes -- we do this now rather -+ * than later because the length will change after we pad. -+ */ -+ be64enc_vect(len, ctx->count, 16); -+ -+ /* Add 1--128 bytes so that the resulting length is 112 mod 128 */ -+ r = (ctx->count[1] >> 3) & 0x7f; -+ plen = (r < 112) ? (112 - r) : (240 - r); -+ SHA512_Update(ctx, PAD, (size_t)plen); -+ -+ /* Add the terminating bit-count */ -+ SHA512_Update(ctx, len, 16); - } - -+/* SHA-512 initialization. Begins a SHA-512 operation. */ -+void -+SHA512_Init(SHA512_CTX * ctx) -+{ - --/* Process the remaining bytes in the internal buffer and the usual -- prolog according to the standard and write the result to RESBUF. -+ /* Zero bits processed so far */ -+ ctx->count[0] = ctx->count[1] = 0; -+ -+ /* Magic initialization constants */ -+ ctx->state[0] = 0x6a09e667f3bcc908ULL; -+ ctx->state[1] = 0xbb67ae8584caa73bULL; -+ ctx->state[2] = 0x3c6ef372fe94f82bULL; -+ ctx->state[3] = 0xa54ff53a5f1d36f1ULL; -+ ctx->state[4] = 0x510e527fade682d1ULL; -+ ctx->state[5] = 0x9b05688c2b3e6c1fULL; -+ ctx->state[6] = 0x1f83d9abfb41bd6bULL; -+ ctx->state[7] = 0x5be0cd19137e2179ULL; -+} - -- IMPORTANT: On some systems it is required that RESBUF is correctly -- aligned for a 32 bits value. */ --void * --sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) -+/* Add bytes into the hash */ -+void -+SHA512_Update(SHA512_CTX * ctx, const void *in, size_t len) - { -- /* Take yet unprocessed bytes into account. */ -- uint32_t bytes = ctx->buflen; -- size_t pad; -- unsigned int i; -- unsigned char *rp = resbuf; -- -- /* Now count remaining bytes. */ -- ctx->total[0] += bytes; -- if (ctx->total[0] < bytes) -- ++ctx->total[1]; -- -- pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; -- /* The first byte of padding should be 0x80 and the rest should be -- zero. (FIPS 180-2:5.1.2) */ -- ctx->buffer[bytes] = 0x80u; -- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1); -- -- /* Put the 128-bit file length in big-endian *bits* at the end of -- the buffer. */ -- cpu_to_be64 (&ctx->buffer[bytes + pad], -- (ctx->total[1] << 3) | (ctx->total[0] >> 61)); -- cpu_to_be64 (&ctx->buffer[bytes + pad + 8], -- ctx->total[0] << 3); -- -- /* Process last bytes. */ -- sha512_process_block (ctx->buffer, bytes + pad + 16, ctx); -- -- /* Put result from CTX in first 64 bytes following RESBUF. */ -- for (i = 0; i < 8; ++i) -- cpu_to_be64 (rp + i*8, ctx->H[i]); -- -- XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha512_ctx)); -- return resbuf; -+ uint64_t bitlen[2]; -+ uint64_t r; -+ const unsigned char *src = in; -+ -+ /* Number of bytes left in the buffer from previous updates */ -+ r = (ctx->count[1] >> 3) & 0x7f; -+ -+ /* Convert the length into a number of bits */ -+ bitlen[1] = ((uint64_t)len) << 3; -+ bitlen[0] = ((uint64_t)len) >> 61; -+ -+ /* Update number of bits */ -+ if ((ctx->count[1] += bitlen[1]) < bitlen[1]) -+ ctx->count[0]++; -+ ctx->count[0] += bitlen[0]; -+ -+ /* Handle the case where we don't need to perform any transforms */ -+ if (len < 128 - r) { -+ memcpy(&ctx->buf[r], src, len); -+ return; -+ } -+ -+ /* Finish the current block */ -+ memcpy(&ctx->buf[r], src, 128 - r); -+ SHA512_Transform(ctx->state, ctx->buf); -+ src += 128 - r; -+ len -= 128 - r; -+ -+ /* Perform complete blocks */ -+ while (len >= 128) { -+ SHA512_Transform(ctx->state, src); -+ src += 128; -+ len -= 128; -+ } -+ -+ /* Copy left over data into buffer */ -+ memcpy(ctx->buf, src, len); - } - -+/* -+ * SHA-512 finalization. Pads the input data, exports the hash value, -+ * and clears the context state. -+ */ -+void -+SHA512_Final(unsigned char digest[64], SHA512_CTX * ctx) -+{ -+ -+ /* Add padding */ -+ SHA512_Pad(ctx); - -+ /* Write the hash */ -+ be64enc_vect(digest, ctx->state, 64); -+ -+ /* Clear the context state */ -+ XCRYPT_SECURE_MEMSET(ctx, sizeof (*ctx)); -+} -+ -+/** -+ * SHA512_Buf(in, len, digest): -+ * Compute the SHA512 hash of ${len} bytes from ${in} and write it to ${digest}. -+ */ - void --sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) -+SHA512_Buf(const void * in, size_t len, uint8_t digest[64]) - { -- /* When we already have some bits in our internal buffer concatenate -- both inputs first. */ -- if (ctx->buflen != 0) -- { -- uint32_t left_over = ctx->buflen; -- uint32_t add = 256 - left_over > len ? (uint32_t)len : 256 - left_over; -- -- memcpy (&ctx->buffer[left_over], buffer, add); -- ctx->buflen += add; -- -- if (ctx->buflen > 128) -- { -- sha512_process_block (ctx->buffer, ctx->buflen & ~127u, ctx); -- -- ctx->buflen &= 127; -- /* The regions in the following copy operation cannot overlap. */ -- memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127u], -- ctx->buflen); -- } -- -- buffer = (const char *) buffer + add; -- len -= add; -- } -- -- /* Process available complete blocks. */ -- if (len > 128) -- { -- sha512_process_block (buffer, len & ~127u, ctx); -- buffer = (const char *) buffer + (len & ~127u); -- len &= 127; -- } -- -- /* Move remaining bytes into internal buffer. */ -- if (len > 0) -- { -- size_t left_over = ctx->buflen; -- -- memcpy (&ctx->buffer[left_over], buffer, len); -- left_over += len; -- if (left_over >= 128) -- { -- sha512_process_block (ctx->buffer, 128, ctx); -- left_over -= 128; -- memcpy (ctx->buffer, &ctx->buffer[128], left_over); -- } -- ctx->buflen = (uint32_t)left_over; -- } -+ SHA512_CTX ctx; -+ -+ SHA512_Init(&ctx); -+ SHA512_Update(&ctx, in, len); -+ SHA512_Final(digest, &ctx); -+ -+ /* Clean the stack. */ -+ XCRYPT_SECURE_MEMSET(&ctx, sizeof(SHA512_CTX)); - } - - #endif -diff --git a/alg-sha512.h b/alg-sha512.h -index c11329e..c591bb1 100644 ---- a/alg-sha512.h -+++ b/alg-sha512.h -@@ -1,46 +1,75 @@ --/* Declaration of functions and data types used for SHA512 sum computing -- library functions. -- Copyright (C) 2007-2017 Free Software Foundation, Inc. -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation; either version 2.1 of -- the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, see -- . */ -- --#ifndef _CRYPT_ALG_SHA512_H --#define _CRYPT_ALG_SHA512_H 1 -- --/* Structure to save state of computation between the single steps. */ --struct sha512_ctx --{ -- uint64_t H[8]; -- -- uint64_t total[2]; -- uint32_t buflen; -- unsigned char buffer[256]; --}; -- --/* Initialize structure containing state of computation. -- (FIPS 180-2: 5.3.3) */ --extern void sha512_init_ctx (struct sha512_ctx *ctx); -- --/* Starting with the result of former calls of this function (or the -- initialization function) update the context for the next LEN bytes -- starting at BUFFER. LEN does not need to be a multiple of 128. */ --extern void sha512_process_bytes (const void *buffer, size_t len, -- struct sha512_ctx *ctx); -- --/* Process the remaining bytes in the buffer and write the finalized -- hash to RESBUF, which should point to 64 bytes of storage. */ --extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf); -- --#endif /* alg-sha512.h */ -+/*- -+ * Copyright 2005 Colin Percival -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+#ifndef _SHA512_H_ -+#define _SHA512_H_ -+ -+#include -+#include -+ -+/* -+ * Use #defines in order to avoid namespace collisions with anyone else's -+ * SHA512 code (e.g., the code in OpenSSL). -+ */ -+#define SHA512_Init libcperciva_SHA512_Init -+#define SHA512_Update libcperciva_SHA512_Update -+#define SHA512_Final libcperciva_SHA512_Final -+#define SHA512_Buf libcperciva_SHA512_Buf -+#define SHA512_CTX libcperciva_SHA512_CTX -+ -+/* Context structure for SHA512 operations. */ -+typedef struct { -+ uint64_t state[8]; -+ uint64_t count[2]; -+ uint8_t buf[128]; -+} SHA512_CTX; -+ -+/** -+ * SHA512_Init(ctx): -+ * Initialize the SHA512 context ${ctx}. -+ */ -+void SHA512_Init(SHA512_CTX *); -+ -+/** -+ * SHA512_Update(ctx, in, len): -+ * Input ${len} bytes from ${in} into the SHA512 context ${ctx}. -+ */ -+void SHA512_Update(SHA512_CTX *, const void *, size_t); -+ -+/** -+ * SHA512_Final(digest, ctx): -+ * Output the SHA512 hash of the data input to the context ${ctx} into the -+ * buffer ${digest}. -+ */ -+void SHA512_Final(uint8_t[64], SHA512_CTX *); -+ -+/** -+ * SHA512_Buf(in, len, digest): -+ * Compute the SHA512 hash of ${len} bytes from ${in} and write it to ${digest}. -+ */ -+void SHA512_Buf(const void *, size_t, uint8_t[64]); -+ -+#endif /* !_SHA512_H_ */ -diff --git a/alg-yescrypt-sysendian.h b/alg-yescrypt-sysendian.h -index e2e41cd..b877e07 100644 ---- a/alg-yescrypt-sysendian.h -+++ b/alg-yescrypt-sysendian.h -@@ -37,6 +37,7 @@ - /* Avoid namespace collisions with BSD . */ - #define be32dec libcperciva_be32dec - #define be32enc libcperciva_be32enc -+#define be64dec libcperciva_be64dec - #define be64enc libcperciva_be64enc - #define le32dec libcperciva_le32dec - #define le32enc libcperciva_le32enc -@@ -61,6 +62,17 @@ be32enc(void * pp, uint32_t x) - p[0] = (x >> 24) & 0xff; - } - -+static inline uint64_t -+be64dec(const void *pp) -+{ -+ const uint8_t *p = (uint8_t const *)pp; -+ -+ return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + -+ ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + -+ ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + -+ ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); -+} -+ - static inline void - be64enc(void * pp, uint64_t x) - { -diff --git a/crypt-port.h b/crypt-port.h -index 5f4d55f..a2c64b3 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -260,9 +260,10 @@ _xcrypt_strcpy_or_abort (void *dst, const size_t d_size, - #endif - - #if INCLUDE_sha512 --#define sha512_finish_ctx _crypt_sha512_finish_ctx --#define sha512_init_ctx _crypt_sha512_init_ctx --#define sha512_process_bytes _crypt_sha512_process_bytes -+#define libcperciva_SHA512_Init _crypt_SHA512_Init -+#define libcperciva_SHA512_Update _crypt_SHA512_Update -+#define libcperciva_SHA512_Final _crypt_SHA512_Final -+#define libcperciva_SHA512_Buf _crypt_SHA512_Buf - #endif - - #if INCLUDE_md5 || INCLUDE_sha256 || INCLUDE_sha512 -diff --git a/crypt-sha512.c b/crypt-sha512.c -index 39ec0b5..2b6b444 100644 ---- a/crypt-sha512.c -+++ b/crypt-sha512.c -@@ -58,7 +58,7 @@ static_assert (SHA512_HASH_LENGTH <= CRYPT_OUTPUT_SIZE, - /* A sha512_buffer holds all of the sensitive intermediate data. */ - struct sha512_buffer - { -- struct sha512_ctx ctx; -+ SHA512_CTX ctx; - uint8_t result[64]; - uint8_t p_bytes[64]; - uint8_t s_bytes[64]; -@@ -77,12 +77,12 @@ static const char b64t[] = - indefinitely. */ - static void - sha512_process_recycled_bytes (unsigned char block[64], size_t len, -- struct sha512_ctx *ctx) -+ SHA512_CTX *ctx) - { - size_t cnt; - for (cnt = len; cnt >= 64; cnt -= 64) -- sha512_process_bytes (block, 64, ctx); -- sha512_process_bytes (block, cnt, ctx); -+ SHA512_Update (ctx, block, 64); -+ SHA512_Update (ctx, block, cnt); - } - - void -@@ -100,7 +100,7 @@ crypt_sha512_rn (const char *phrase, size_t phr_size, - } - - struct sha512_buffer *buf = scratch; -- struct sha512_ctx *ctx = &buf->ctx; -+ SHA512_CTX *ctx = &buf->ctx; - uint8_t *result = buf->result; - uint8_t *p_bytes = buf->p_bytes; - uint8_t *s_bytes = buf->s_bytes; -@@ -158,80 +158,80 @@ crypt_sha512_rn (const char *phrase, size_t phr_size, - - /* Compute alternate SHA512 sum with input PHRASE, SALT, and PHRASE. The - final result will be added to the first context. */ -- sha512_init_ctx (ctx); -+ SHA512_Init (ctx); - - /* Add phrase. */ -- sha512_process_bytes (phrase, phr_size, ctx); -+ SHA512_Update (ctx, phrase, phr_size); - - /* Add salt. */ -- sha512_process_bytes (salt, salt_size, ctx); -+ SHA512_Update (ctx, salt, salt_size); - - /* Add phrase again. */ -- sha512_process_bytes (phrase, phr_size, ctx); -+ SHA512_Update (ctx, phrase, phr_size); - - /* Now get result of this (64 bytes) and add it to the other - context. */ -- sha512_finish_ctx (ctx, result); -+ SHA512_Final (result, ctx); - - /* Prepare for the real work. */ -- sha512_init_ctx (ctx); -+ SHA512_Init (ctx); - - /* Add the phrase string. */ -- sha512_process_bytes (phrase, phr_size, ctx); -+ SHA512_Update (ctx, phrase, phr_size); - - /* The last part is the salt string. This must be at most 8 - characters and it ends at the first `$' character (for - compatibility with existing implementations). */ -- sha512_process_bytes (salt, salt_size, ctx); -+ SHA512_Update (ctx, salt, salt_size); - - /* Add for any character in the phrase one byte of the alternate sum. */ - for (cnt = phr_size; cnt > 64; cnt -= 64) -- sha512_process_bytes (result, 64, ctx); -- sha512_process_bytes (result, cnt, ctx); -+ SHA512_Update (ctx, result, 64); -+ SHA512_Update (ctx, result, cnt); - - /* Take the binary representation of the length of the phrase and for every - 1 add the alternate sum, for every 0 the phrase. */ - for (cnt = phr_size; cnt > 0; cnt >>= 1) - if ((cnt & 1) != 0) -- sha512_process_bytes (result, 64, ctx); -+ SHA512_Update (ctx, result, 64); - else -- sha512_process_bytes (phrase, phr_size, ctx); -+ SHA512_Update (ctx, phrase, phr_size); - - /* Create intermediate result. */ -- sha512_finish_ctx (ctx, result); -+ SHA512_Final (result, ctx); - - /* Start computation of P byte sequence. */ -- sha512_init_ctx (ctx); -+ SHA512_Init (ctx); - - /* For every character in the password add the entire password. */ - for (cnt = 0; cnt < phr_size; ++cnt) -- sha512_process_bytes (phrase, phr_size, ctx); -+ SHA512_Update (ctx, phrase, phr_size); - - /* Finish the digest. */ -- sha512_finish_ctx (ctx, p_bytes); -+ SHA512_Final (p_bytes, ctx); - - /* Start computation of S byte sequence. */ -- sha512_init_ctx (ctx); -+ SHA512_Init (ctx); - - /* For every character in the password add the entire password. */ - for (cnt = 0; cnt < (size_t) 16 + (size_t) result[0]; ++cnt) -- sha512_process_bytes (salt, salt_size, ctx); -+ SHA512_Update (ctx, salt, salt_size); - - /* Finish the digest. */ -- sha512_finish_ctx (ctx, s_bytes); -+ SHA512_Final (s_bytes, ctx); - - /* Repeatedly run the collected hash value through SHA512 to burn - CPU cycles. */ - for (cnt = 0; cnt < rounds; ++cnt) - { - /* New context. */ -- sha512_init_ctx (ctx); -+ SHA512_Init (ctx); - - /* Add phrase or last result. */ - if ((cnt & 1) != 0) - sha512_process_recycled_bytes (p_bytes, phr_size, ctx); - else -- sha512_process_bytes (result, 64, ctx); -+ SHA512_Update (ctx, result, 64); - - /* Add salt for numbers not divisible by 3. */ - if (cnt % 3 != 0) -@@ -243,12 +243,12 @@ crypt_sha512_rn (const char *phrase, size_t phr_size, - - /* Add phrase or last result. */ - if ((cnt & 1) != 0) -- sha512_process_bytes (result, 64, ctx); -+ SHA512_Update (ctx, result, 64); - else - sha512_process_recycled_bytes (p_bytes, phr_size, ctx); - - /* Create intermediate result. */ -- sha512_finish_ctx (ctx, result); -+ SHA512_Final (result, ctx); - } - - /* Now we can construct the result string. It consists of four -diff --git a/test-alg-sha512.c b/test-alg-sha512.c -index b6d4fc6..5f9af9c 100644 ---- a/test-alg-sha512.c -+++ b/test-alg-sha512.c -@@ -84,7 +84,7 @@ static const struct - - static void - report_failure(int n, const char *tag, -- const char expected[64], const char actual[64]) -+ const char expected[64], const uint8_t actual[64]) - { - int i; - printf ("FAIL: test %d (%s):\n exp:", n, tag); -@@ -112,28 +112,25 @@ report_failure(int n, const char *tag, - int - main (void) - { -- struct sha512_ctx ctx; -- char sum[64]; -+ SHA512_CTX ctx; -+ uint8_t sum[64]; - int result = 0; - int cnt; - int i; - - for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { -- sha512_init_ctx (&ctx); -- sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), -- &ctx); -- sha512_finish_ctx (&ctx, sum); -+ SHA512_Buf (tests[cnt].input, strlen (tests[cnt].input), sum); - if (memcmp (tests[cnt].result, sum, 64) != 0) - { - report_failure (cnt, "all at once", tests[cnt].result, sum); - result = 1; - } - -- sha512_init_ctx (&ctx); -+ SHA512_Init (&ctx); - for (i = 0; tests[cnt].input[i] != '\0'; ++i) -- sha512_process_bytes (&tests[cnt].input[i], 1, &ctx); -- sha512_finish_ctx (&ctx, sum); -+ SHA512_Update (&ctx, &tests[cnt].input[i], 1); -+ SHA512_Final (sum, &ctx); - if (memcmp (tests[cnt].result, sum, 64) != 0) - { - report_failure (cnt, "byte by byte", tests[cnt].result, sum); -@@ -144,10 +141,10 @@ main (void) - /* Test vector from FIPS 180-2: appendix C.3. */ - char buf[1000]; - memset (buf, 'a', sizeof (buf)); -- sha512_init_ctx (&ctx); -+ SHA512_Init (&ctx); - for (i = 0; i < 1000; ++i) -- sha512_process_bytes (buf, sizeof (buf), &ctx); -- sha512_finish_ctx (&ctx, sum); -+ SHA512_Update (&ctx, buf, sizeof (buf)); -+ SHA512_Final (sum, &ctx); - static const char expected[64] = - "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" - "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" - -From 4964877dbf96d951b3f45b2dba97459404d1dff8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 22 Oct 2018 13:48:34 +0200 -Subject: [PATCH 10/17] Use md5 implementation from Alexander Peslyak. - -Thus we now have a md5 implementation in the public domain. ---- - LICENSING | 5 +- - NEWS | 2 + - TODO.md | 2 - - alg-md5.c | 539 ++++++++++++++++++++++++------------------------- - alg-md5.h | 79 ++++---- - crypt-md5.c | 47 +++-- - crypt-port.h | 6 +- - crypt-sunmd5.c | 20 +- - test-alg-md5.c | 24 +-- - 9 files changed, 349 insertions(+), 375 deletions(-) - -diff --git a/LICENSING b/LICENSING -index 31f704c..0ed22f5 100644 ---- a/LICENSING -+++ b/LICENSING -@@ -13,7 +13,7 @@ source tree. For specific licensing terms consult the files themselves. - - * Copyright Free Software Foundation, Inc.; LGPL (v2.1 or later): - crypt.h, crypt-obsolete.h, crypt-private.h -- alg-md5.h, alg-md5.c, crypt-md5.c, -+ crypt-md5.c, - test-crypt-badsalt.c, test-crypt-nonnull.c - - * Copyright David Burren et al.; 3-clause BSD: -@@ -24,7 +24,8 @@ source tree. For specific licensing terms consult the files themselves. - crypt-sha256.c, crypt-sha512.c - - * Public domain, written by Solar Designer et al.: -- alg-md4.h, alg-md4.c, crypt-bcrypt.c, crypt-gensalt.c, test-crypt-bcrypt.c -+ alg-md4.h, alg-md4.c, alg-md5.h, alg-md5.c, -+ crypt-bcrypt.c, crypt-gensalt.c, test-crypt-bcrypt.c - - * Copyright Solar Designer, Colin Percival; 0-clause BSD: - alg-yescrypt-common.c, alg-yescrypt-platform.c -diff --git a/NEWS b/NEWS -index c4b04da..e48b0d1 100644 ---- a/NEWS -+++ b/NEWS -@@ -8,6 +8,8 @@ Version 4.2.3 - tarball release, use './bootstrap' to create the configure script. - * Use sha512 implementation from Colin Percival. Thus we now have a - sha512 implementation under the BSD license. -+* Use md5 implementation from Alexander Peslyak. Thus we now have a -+ md5 implementation in the public domain. - - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. -diff --git a/TODO.md b/TODO.md -index c4e2799..7df4ca5 100644 ---- a/TODO.md -+++ b/TODO.md -@@ -95,8 +95,6 @@ It was last updated 20 October 2018. - at it, and no destructor function - - * Permissive relicensing, to encourage use beyond the GNU ecosystem? -- * Replace remaining (L)GPLed crypto primitives (MD5) with -- permissively licensed equivalents (e.g. from Openwall) - * Replace crypt-md5.c with original md5crypt from FreeBSD? - * Other files subject to the (L)GPL are crypt.c, crypt-static.c, - crypt-gensalt-static.c, crypt-obsolete.h, crypt-port.h, -diff --git a/alg-md5.c b/alg-md5.c -index 9d9e4e3..8382b98 100644 ---- a/alg-md5.c -+++ b/alg-md5.c -@@ -1,308 +1,291 @@ --/* Functions to compute MD5 message digest of files or memory blocks. -- according to the definition of MD5 in RFC 1321 from April 1992. -- -- Copyright (C) 1995-2017 Free Software Foundation, Inc. -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation; either version 2.1 of -- the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, see -- . */ -- --/* Written by Ulrich Drepper , 1995. */ -+/* -+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. -+ * MD5 Message-Digest Algorithm (RFC 1321). -+ * -+ * Homepage: -+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 -+ * -+ * Author: -+ * Alexander Peslyak, better known as Solar Designer -+ * -+ * This software was written by Alexander Peslyak in 2001. No copyright is -+ * claimed, and the software is hereby placed in the public domain. -+ * In case this attempt to disclaim copyright and place the software in the -+ * public domain is deemed null and void, then the software is -+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the -+ * general public under the following terms: -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted. -+ * -+ * There's ABSOLUTELY NO WARRANTY, express or implied. -+ * -+ * (This is a heavily cut-down "BSD license".) -+ * -+ * This differs from Colin Plumb's older public domain implementation in that -+ * no exactly 32-bit integer data type is required (any 32-bit or wider -+ * unsigned integer data type will do), there's no compile-time endianness -+ * configuration, and the function prototypes match OpenSSL's. No code from -+ * Colin Plumb's implementation has been reused; this comment merely compares -+ * the properties of the two independent implementations. -+ * -+ * The primary goals of this implementation are portability and ease of use. -+ * It is meant to be fast, but not as fast as possible. Some known -+ * optimizations are not included to reduce source code size and avoid -+ * compile-time configuration. -+ */ - - #include "crypt-port.h" --#include "alg-md5.h" --#include "byteorder.h" - - #if INCLUDE_md5 || INCLUDE_sunmd5 - --static void md5_process_block (const void *buffer, size_t len, -- struct md5_ctx *ctx); -+#include "alg-md5.h" - --/* Initialize structure containing state of computation. -- (RFC 1321, 3.3: Step 3) */ --void --md5_init_ctx (struct md5_ctx *ctx) --{ -- ctx->A = 0x67452301; -- ctx->B = 0xefcdab89; -- ctx->C = 0x98badcfe; -- ctx->D = 0x10325476; -+/* -+ * The basic MD5 functions. -+ * -+ * F and G are optimized compared to their RFC 1321 definitions for -+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's -+ * implementation. -+ */ -+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -+#define H(x, y, z) (((x) ^ (y)) ^ (z)) -+#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -+#define I(x, y, z) ((y) ^ ((x) | ~(z))) -+ -+/* -+ * The MD5 transformation for all four rounds. -+ */ -+#define STEP(f, a, b, c, d, x, t, s) \ -+ (a) += f((b), (c), (d)) + (x) + (t); \ -+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ -+ (a) += (b); -+ -+/* -+ * SET reads 4 input bytes in little-endian byte order and stores them in a -+ * properly aligned word in host byte order. -+ * -+ * The check for little-endian architectures that tolerate unaligned memory -+ * accesses is just an optimization. Nothing will break if it fails to detect -+ * a suitable architecture. -+ * -+ * Unfortunately, this optimization may be a C strict aliasing rules violation -+ * if the caller's data buffer has effective type that cannot be aliased by -+ * MD5_u32plus. In practice, this problem may occur if these MD5 routines are -+ * inlined into a calling function, or with future and dangerously advanced -+ * link-time optimizations. For the time being, keeping these MD5 routines in -+ * their own translation unit avoids the problem. -+ */ -+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -+#define SET(n) \ -+ (*(const MD5_u32plus *)&ptr[(n) * 4]) -+#define GET(n) \ -+ SET(n) -+#else -+#define SET(n) \ -+ (ctx->block[(n)] = \ -+ (MD5_u32plus)ptr[(n) * 4] | \ -+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ -+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ -+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) -+#define GET(n) \ -+ (ctx->block[(n)]) -+#endif - -- ctx->total = 0; -- ctx->buflen = 0; -+/* -+ * This processes one or more 64-byte data blocks, but does NOT update the bit -+ * counters. There are no alignment requirements. -+ */ -+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) -+{ -+ const unsigned char *ptr; -+ MD5_u32plus a, b, c, d; -+ MD5_u32plus saved_a, saved_b, saved_c, saved_d; -+ -+ ptr = (const unsigned char *)data; -+ -+ a = ctx->a; -+ b = ctx->b; -+ c = ctx->c; -+ d = ctx->d; -+ -+ do { -+ saved_a = a; -+ saved_b = b; -+ saved_c = c; -+ saved_d = d; -+ -+/* Round 1 */ -+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) -+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) -+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17) -+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) -+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) -+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) -+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) -+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) -+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) -+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) -+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) -+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) -+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) -+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) -+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) -+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) -+ -+/* Round 2 */ -+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) -+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) -+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) -+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) -+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) -+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9) -+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) -+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) -+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) -+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) -+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) -+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) -+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) -+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) -+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) -+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) -+ -+/* Round 3 */ -+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) -+ STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) -+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) -+ STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) -+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) -+ STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) -+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) -+ STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) -+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) -+ STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) -+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) -+ STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) -+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) -+ STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) -+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) -+ STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) -+ -+/* Round 4 */ -+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) -+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) -+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) -+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) -+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) -+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) -+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) -+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) -+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) -+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) -+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) -+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) -+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) -+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) -+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) -+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) -+ -+ a += saved_a; -+ b += saved_b; -+ c += saved_c; -+ d += saved_d; -+ -+ ptr += 64; -+ } while (size -= 64); -+ -+ ctx->a = a; -+ ctx->b = b; -+ ctx->c = c; -+ ctx->d = d; -+ -+ return ptr; - } - --/* Put result from CTX in first 16 bytes following RESBUF. The result -- will be in little endian byte order. */ --static void * --md5_read_ctx (struct md5_ctx *ctx, void *resbuf) -+void MD5_Init(MD5_CTX *ctx) - { -- unsigned char *buf = resbuf; -- cpu_to_le32 (buf + 0, ctx->A); -- cpu_to_le32 (buf + 4, ctx->B); -- cpu_to_le32 (buf + 8, ctx->C); -- cpu_to_le32 (buf + 12, ctx->D); -- XCRYPT_SECURE_MEMSET (ctx, sizeof(*ctx)); -- return resbuf; --} -+ ctx->a = 0x67452301; -+ ctx->b = 0xefcdab89; -+ ctx->c = 0x98badcfe; -+ ctx->d = 0x10325476; - --/* Process the remaining bytes in the internal buffer and the usual -- prolog according to the standard and write the result to RESBUF. */ -+ ctx->lo = 0; -+ ctx->hi = 0; -+} - --void * --md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) -+void MD5_Update(MD5_CTX *ctx, const void *data, size_t size) - { -- /* Take yet unprocessed bytes into account. */ -- uint32_t bytes = ctx->buflen; -- size_t pad; -+ MD5_u32plus saved_lo; -+ unsigned long used, available; -+ -+ saved_lo = ctx->lo; -+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) -+ ctx->hi++; -+ ctx->hi += (MD5_u32plus) size >> 29; - -- /* Now count remaining bytes. */ -- ctx->total += bytes; -+ used = saved_lo & 0x3f; - -- pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; -+ if (used) { -+ available = 64 - used; - -- /* The first byte of padding should be 0x80 and the rest should be -- zero. (RFC 1321, 3.1: Step 1) */ -- ctx->buffer[bytes] = 0x80u; -- XCRYPT_SECURE_MEMSET (&ctx->buffer[bytes+1], pad-1); -+ if (size < available) { -+ memcpy(&ctx->buffer[used], data, size); -+ return; -+ } - -- /* Put the 64-bit file length in little-endian *bits* at the end of -- the buffer. */ -- cpu_to_le64 (&ctx->buffer[bytes + pad], ctx->total << 3); -+ memcpy(&ctx->buffer[used], data, available); -+ data = (const unsigned char *)data + available; -+ size -= available; -+ body(ctx, ctx->buffer, 64); -+ } - -- /* Process last bytes. */ -- md5_process_block (ctx->buffer, bytes + pad + 8, ctx); -+ if (size >= 64) { -+ data = body(ctx, data, size & ~(unsigned long)0x3f); -+ size &= 0x3f; -+ } - -- return md5_read_ctx (ctx, resbuf); -+ memcpy(ctx->buffer, data, size); - } - -+#define OUT(dst, src) \ -+ (dst)[0] = (unsigned char)(src); \ -+ (dst)[1] = (unsigned char)((src) >> 8); \ -+ (dst)[2] = (unsigned char)((src) >> 16); \ -+ (dst)[3] = (unsigned char)((src) >> 24); - --void --md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) -+void MD5_Final(uint8_t result[16], MD5_CTX *ctx) - { -- /* When we already have some bits in our internal buffer concatenate -- both inputs first. */ -- if (ctx->buflen != 0) -- { -- uint32_t left_over = ctx->buflen; -- uint32_t add = 128 - left_over > len ? (uint32_t)len : 128 - left_over; -- -- memcpy (&ctx->buffer[left_over], buffer, add); -- ctx->buflen += add; -- -- if (ctx->buflen > 64) -- { -- md5_process_block (ctx->buffer, ctx->buflen & ~63u, ctx); -- -- ctx->buflen &= 63; -- /* The regions in the following copy operation cannot overlap. */ -- memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63u], -- ctx->buflen); -- } -- -- buffer = (const char *) buffer + add; -- len -= add; -- } -- -- /* Process available complete blocks. */ -- if (len > 64) -- { -- md5_process_block (buffer, len & ~63u, ctx); -- buffer = (const char *) buffer + (len & ~63u); -- len &= 63; -- } -- -- /* Move remaining bytes in internal buffer. */ -- if (len > 0) -- { -- uint32_t left_over = ctx->buflen; -- -- memcpy (&ctx->buffer[left_over], buffer, len); -- left_over += (uint32_t)len; -- if (left_over >= 64) -- { -- md5_process_block (ctx->buffer, 64, ctx); -- left_over -= 64; -- memcpy (ctx->buffer, &ctx->buffer[64], left_over); -- } -- ctx->buflen = left_over; -- } --} -+ unsigned long used, available; - -+ used = ctx->lo & 0x3f; - --/* These are the four functions used in the four steps of the MD5 algorithm -- and defined in the RFC 1321. The first function is a little bit optimized -- (as found in Colin Plumbs public domain implementation). */ --/* #define FF(b, c, d) ((b & c) | (~b & d)) */ --#define FF(b, c, d) (d ^ (b & (c ^ d))) --#define FG(b, c, d) FF (d, b, c) --#define FH(b, c, d) (b ^ c ^ d) --#define FI(b, c, d) (c ^ (b | ~d)) -+ ctx->buffer[used++] = 0x80; - --/* Process LEN bytes of BUFFER, accumulating context into CTX. -- It is assumed that LEN % 64 == 0. */ -+ available = 64 - used; - --static void --md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) --{ -- const unsigned char *p = buffer; -- const unsigned char *endp = p + len; -- uint32_t A = ctx->A; -- uint32_t B = ctx->B; -- uint32_t C = ctx->C; -- uint32_t D = ctx->D; -- -- /* First increment the byte count. RFC 1321 specifies the possible -- length of the file up to 2^64 bits. Here we only compute the -- number of bytes. */ -- ctx->total += len; -- -- /* Process all bytes in the buffer with 64 bytes in each round of -- the loop. */ -- while (p < endp) -- { -- uint32_t *cwp = ctx->correct_words; -- uint32_t A_save = A; -- uint32_t B_save = B; -- uint32_t C_save = C; -- uint32_t D_save = D; -- -- /* First round: using the given function, the context and a constant -- the next context is computed. Because the algorithms 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. */ -- --#define OP(a, b, c, d, s, T) \ -- do \ -- { \ -- uint32_t word = le32_to_cpu (p); \ -- p += 4; \ -- *cwp++ = word; \ -- a += FF (b, c, d) + word + T; \ -- CYCLIC (a, s); \ -- a += b; \ -- } \ -- while (0) -- -- /* It is unfortunate that C does not provide an operator for -- cyclic rotation. Hope the C compiler is smart enough. */ --#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) -- -- /* 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 -- */ -- -- /* Round 1. */ -- OP (A, B, C, D, 7, 0xd76aa478); -- OP (D, A, B, C, 12, 0xe8c7b756); -- OP (C, D, A, B, 17, 0x242070db); -- OP (B, C, D, A, 22, 0xc1bdceee); -- OP (A, B, C, D, 7, 0xf57c0faf); -- OP (D, A, B, C, 12, 0x4787c62a); -- OP (C, D, A, B, 17, 0xa8304613); -- OP (B, C, D, A, 22, 0xfd469501); -- OP (A, B, C, D, 7, 0x698098d8); -- OP (D, A, B, C, 12, 0x8b44f7af); -- OP (C, D, A, B, 17, 0xffff5bb1); -- OP (B, C, D, A, 22, 0x895cd7be); -- OP (A, B, C, D, 7, 0x6b901122); -- OP (D, A, B, C, 12, 0xfd987193); -- OP (C, D, A, B, 17, 0xa679438e); -- OP (B, C, D, A, 22, 0x49b40821); -- -- /* For the second to fourth round we have the possibly swapped words -- in CORRECT_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) \ -- do \ -- { \ -- a += f (b, c, d) + ctx->correct_words[k] + T; \ -- CYCLIC (a, s); \ -- a += b; \ -- } \ -- while (0) -- -- /* Round 2. */ -- OP (FG, A, B, C, D, 1, 5, 0xf61e2562); -- OP (FG, D, A, B, C, 6, 9, 0xc040b340); -- OP (FG, C, D, A, B, 11, 14, 0x265e5a51); -- OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); -- OP (FG, A, B, C, D, 5, 5, 0xd62f105d); -- OP (FG, D, A, B, C, 10, 9, 0x02441453); -- OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); -- OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); -- OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); -- OP (FG, D, A, B, C, 14, 9, 0xc33707d6); -- OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); -- OP (FG, B, C, D, A, 8, 20, 0x455a14ed); -- OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); -- 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); -- -- /* Round 3. */ -- OP (FH, A, B, C, D, 5, 4, 0xfffa3942); -- OP (FH, D, A, B, C, 8, 11, 0x8771f681); -- OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); -- OP (FH, B, C, D, A, 14, 23, 0xfde5380c); -- OP (FH, A, B, C, D, 1, 4, 0xa4beea44); -- OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); -- OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); -- OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); -- OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); -- OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); -- OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); -- OP (FH, B, C, D, A, 6, 23, 0x04881d05); -- OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); -- 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); -- -- /* Round 4. */ -- OP (FI, A, B, C, D, 0, 6, 0xf4292244); -- OP (FI, D, A, B, C, 7, 10, 0x432aff97); -- OP (FI, C, D, A, B, 14, 15, 0xab9423a7); -- OP (FI, B, C, D, A, 5, 21, 0xfc93a039); -- OP (FI, A, B, C, D, 12, 6, 0x655b59c3); -- OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); -- OP (FI, C, D, A, B, 10, 15, 0xffeff47d); -- OP (FI, B, C, D, A, 1, 21, 0x85845dd1); -- OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); -- OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); -- OP (FI, C, D, A, B, 6, 15, 0xa3014314); -- OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); -- OP (FI, A, B, C, D, 4, 6, 0xf7537e82); -- 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); -- -- /* 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; -+ if (available < 8) { -+ XCRYPT_SECURE_MEMSET(&ctx->buffer[used], available); -+ body(ctx, ctx->buffer, 64); -+ used = 0; -+ available = 64; -+ } -+ -+ XCRYPT_SECURE_MEMSET(&ctx->buffer[used], available - 8); -+ -+ ctx->lo <<= 3; -+ OUT(&ctx->buffer[56], ctx->lo) -+ OUT(&ctx->buffer[60], ctx->hi) -+ -+ body(ctx, ctx->buffer, 64); -+ -+ OUT(&result[0], ctx->a) -+ OUT(&result[4], ctx->b) -+ OUT(&result[8], ctx->c) -+ OUT(&result[12], ctx->d) -+ -+ XCRYPT_SECURE_MEMSET(ctx, sizeof(*ctx)); - } - - #endif -diff --git a/alg-md5.h b/alg-md5.h -index a56aba9..1947eb3 100644 ---- a/alg-md5.h -+++ b/alg-md5.h -@@ -1,52 +1,43 @@ --/* Declaration of functions and data types used for MD5 sum computing -- library functions. -- -- Copyright (C) 1995-2017 Free Software Foundation, Inc. -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation; either version 2.1 of -- the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, see -- . */ -+/* -+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. -+ * MD5 Message-Digest Algorithm (RFC 1321). -+ * -+ * Homepage: -+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 -+ * -+ * Author: -+ * Alexander Peslyak, better known as Solar Designer -+ * -+ * This software was written by Alexander Peslyak in 2001. No copyright is -+ * claimed, and the software is hereby placed in the public domain. -+ * In case this attempt to disclaim copyright and place the software in the -+ * public domain is deemed null and void, then the software is -+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the -+ * general public under the following terms: -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted. -+ * -+ * There's ABSOLUTELY NO WARRANTY, express or implied. -+ * -+ * See md5.c for more information. -+ */ - - #ifndef _CRYPT_ALG_MD5_H - #define _CRYPT_ALG_MD5_H 1 - --/* Structure to save state of computation between the single steps. */ --struct md5_ctx --{ -- uint32_t A; -- uint32_t B; -- uint32_t C; -- uint32_t D; -- -- uint64_t total; -- uint32_t buflen; -- uint32_t correct_words[16]; -- unsigned char buffer[128]; --}; -- --/* Initialize structure containing state of computation. -- (RFC 1321, 3.3: Step 3) */ --extern void md5_init_ctx (struct md5_ctx *ctx); -+/* Any 32-bit or wider unsigned integer data type will do */ -+typedef uint32_t MD5_u32plus; - --/* Starting with the result of former calls of this function (or the -- initialization function) update the context for the next LEN bytes -- starting at BUFFER. LEN does not need to be a multiple of 64. */ --extern void md5_process_bytes (const void *buffer, size_t len, -- struct md5_ctx *ctx); -+typedef struct { -+ MD5_u32plus lo, hi; -+ MD5_u32plus a, b, c, d; -+ uint8_t buffer[64]; -+ MD5_u32plus block[16]; -+} MD5_CTX; - --/* Process the remaining bytes in the buffer and write the finalized -- hash to RESBUF, which should point to 16 bytes of storage. All -- data written to CTX is erased before returning from the function. */ --extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); -+extern void MD5_Init(MD5_CTX *ctx); -+extern void MD5_Update(MD5_CTX *ctx, const void *data, size_t size); -+extern void MD5_Final(uint8_t result[16], MD5_CTX *ctx); - - #endif /* alg-md5.h */ -diff --git a/crypt-md5.c b/crypt-md5.c -index f64b6fc..108c31c 100644 ---- a/crypt-md5.c -+++ b/crypt-md5.c -@@ -50,7 +50,7 @@ static_assert (MD5_HASH_LENGTH <= CRYPT_OUTPUT_SIZE, - /* An md5_buffer holds all of the sensitive intermediate data. */ - struct md5_buffer - { -- struct md5_ctx ctx; -+ MD5_CTX ctx; - uint8_t result[16]; - }; - -@@ -74,7 +74,7 @@ crypt_md5_rn (const char *phrase, size_t phr_size, - } - - struct md5_buffer *buf = scratch; -- struct md5_ctx *ctx = &buf->ctx; -+ MD5_CTX *ctx = &buf->ctx; - uint8_t *result = buf->result; - char *cp = (char *)output; - const char *salt = setting; -@@ -99,40 +99,40 @@ crypt_md5_rn (const char *phrase, size_t phr_size, - - /* Compute alternate MD5 sum with input PHRASE, SALT, and PHRASE. The - final result will be added to the first context. */ -- md5_init_ctx (ctx); -+ MD5_Init (ctx); - - /* Add phrase. */ -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - - /* Add salt. */ -- md5_process_bytes (salt, salt_size, ctx); -+ MD5_Update (ctx, salt, salt_size); - - /* Add phrase again. */ -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - - /* Now get result of this (16 bytes). */ -- md5_finish_ctx (ctx, result); -+ MD5_Final (result, ctx); - - /* Prepare for the real work. */ -- md5_init_ctx (ctx); -+ MD5_Init (ctx); - - /* Add the phrase string. */ -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - - /* Because the SALT argument need not always have the salt prefix we - add it separately. */ -- md5_process_bytes (md5_salt_prefix, sizeof (md5_salt_prefix) - 1, ctx); -+ MD5_Update (ctx, md5_salt_prefix, sizeof (md5_salt_prefix) - 1); - - /* The last part is the salt string. This must be at most 8 - characters and it ends at the first `$' character (for - compatibility with existing implementations). */ -- md5_process_bytes (salt, salt_size, ctx); -+ MD5_Update (ctx, salt, salt_size); - - - /* Add for any character in the phrase one byte of the alternate sum. */ - for (cnt = phr_size; cnt > 16; cnt -= 16) -- md5_process_bytes (result, 16, ctx); -- md5_process_bytes (result, cnt, ctx); -+ MD5_Update (ctx, result, 16); -+ MD5_Update (ctx, result, cnt); - - /* For the following code we need a NUL byte. */ - *result = '\0'; -@@ -142,11 +142,10 @@ crypt_md5_rn (const char *phrase, size_t phr_size, - bit the first character of the phrase. This does not seem to be - what was intended but we have to follow this to be compatible. */ - for (cnt = phr_size; cnt > 0; cnt >>= 1) -- md5_process_bytes ((cnt & 1) != 0 ? (const char *) result : phrase, 1, -- ctx); -+ MD5_Update (ctx, (cnt & 1) != 0 ? (const char *) result : phrase, 1); - - /* Create intermediate result. */ -- md5_finish_ctx (ctx, result); -+ MD5_Final (result, ctx); - - /* Now comes another weirdness. In fear of password crackers here - comes a quite long loop which just processes the output of the -@@ -154,30 +153,30 @@ crypt_md5_rn (const char *phrase, size_t phr_size, - for (cnt = 0; cnt < 1000; ++cnt) - { - /* New context. */ -- md5_init_ctx (ctx); -+ MD5_Init (ctx); - - /* Add phrase or last result. */ - if ((cnt & 1) != 0) -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - else -- md5_process_bytes (result, 16, ctx); -+ MD5_Update (ctx, result, 16); - - /* Add salt for numbers not divisible by 3. */ - if (cnt % 3 != 0) -- md5_process_bytes (salt, salt_size, ctx); -+ MD5_Update (ctx, salt, salt_size); - - /* Add phrase for numbers not divisible by 7. */ - if (cnt % 7 != 0) -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - - /* Add phrase or last result. */ - if ((cnt & 1) != 0) -- md5_process_bytes (result, 16, ctx); -+ MD5_Update (ctx, result, 16); - else -- md5_process_bytes (phrase, phr_size, ctx); -+ MD5_Update (ctx, phrase, phr_size); - - /* Create intermediate result. */ -- md5_finish_ctx (ctx, result); -+ MD5_Final (result, ctx); - } - - /* Now we can construct the result string. It consists of three -diff --git a/crypt-port.h b/crypt-port.h -index a2c64b3..2571c94 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -247,9 +247,9 @@ _xcrypt_strcpy_or_abort (void *dst, const size_t d_size, - #endif - - #if INCLUDE_md5 || INCLUDE_sunmd5 --#define md5_finish_ctx _crypt_md5_finish_ctx --#define md5_init_ctx _crypt_md5_init_ctx --#define md5_process_bytes _crypt_md5_process_bytes -+#define MD5_Init _crypt_MD5_Init -+#define MD5_Update _crypt_MD5_Update -+#define MD5_Final _crypt_MD5_Final - #endif - - #if INCLUDE_sha1 -diff --git a/crypt-sunmd5.c b/crypt-sunmd5.c -index 9f76ed1..7a30aae 100644 ---- a/crypt-sunmd5.c -+++ b/crypt-sunmd5.c -@@ -165,7 +165,7 @@ crypt_sunmd5_rn (const char *phrase, size_t phr_size, - { - struct crypt_sunmd5_scratch - { -- struct md5_ctx ctx; -+ MD5_CTX ctx; - uint8_t dg[16]; - char rn[16]; - }; -@@ -238,27 +238,27 @@ crypt_sunmd5_rn (const char *phrase, size_t phr_size, - struct crypt_sunmd5_scratch *s = scratch; - - /* Initial round. */ -- md5_init_ctx (&s->ctx); -- md5_process_bytes (phrase, phr_size, &s->ctx); -- md5_process_bytes (setting, saltlen, &s->ctx); -- md5_finish_ctx (&s->ctx, s->dg); -+ MD5_Init (&s->ctx); -+ MD5_Update (&s->ctx, phrase, phr_size); -+ MD5_Update (&s->ctx, setting, saltlen); -+ MD5_Final (s->dg, &s->ctx); - - /* Stretching rounds. */ - for (unsigned int i = 0; i < nrounds; i++) - { -- md5_init_ctx (&s->ctx); -+ MD5_Init (&s->ctx); - -- md5_process_bytes (s->dg, sizeof s->dg, &s->ctx); -+ MD5_Update (&s->ctx, s->dg, sizeof s->dg); - - /* The trailing nul is intentionally included. */ - if (muffet_coin_toss (s->dg, i)) -- md5_process_bytes (hamlet_quotation, sizeof hamlet_quotation, &s->ctx); -+ MD5_Update (&s->ctx, hamlet_quotation, sizeof hamlet_quotation); - - int nwritten = snprintf (s->rn, sizeof s->rn, "%u", i); - assert (nwritten >= 1 && (unsigned int)nwritten + 1 <= sizeof s->rn); -- md5_process_bytes (s->rn, (unsigned int)nwritten, &s->ctx); -+ MD5_Update (&s->ctx, s->rn, (unsigned int)nwritten); - -- md5_finish_ctx (&s->ctx, s->dg); -+ MD5_Final (s->dg, &s->ctx); - } - - memcpy (output, setting, saltlen); -diff --git a/test-alg-md5.c b/test-alg-md5.c -index dabc6ba..21c4309 100644 ---- a/test-alg-md5.c -+++ b/test-alg-md5.c -@@ -52,7 +52,7 @@ static const struct - - static void - report_failure(int n, const char *tag, -- const char expected[16], const char actual[16]) -+ const char expected[16], uint8_t actual[16]) - { - int i; - printf ("FAIL: test %d (%s):\n exp:", n, tag); -@@ -76,27 +76,27 @@ report_failure(int n, const char *tag, - int - main (void) - { -- struct md5_ctx ctx; -- char sum[16]; -+ MD5_CTX ctx; -+ uint8_t sum[16]; - int result = 0; - int cnt; - int i; - - for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { -- md5_init_ctx (&ctx); -- md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); -- md5_finish_ctx (&ctx, sum); -+ MD5_Init (&ctx); -+ MD5_Update (&ctx, tests[cnt].input, strlen (tests[cnt].input)); -+ MD5_Final (sum, &ctx); - if (memcmp (tests[cnt].result, sum, 16)) - { - report_failure (cnt, "all at once", tests[cnt].result, sum); - result = 1; - } - -- md5_init_ctx (&ctx); -+ MD5_Init (&ctx); - for (i = 0; tests[cnt].input[i] != '\0'; ++i) -- md5_process_bytes (&tests[cnt].input[i], 1, &ctx); -- md5_finish_ctx (&ctx, sum); -+ MD5_Update (&ctx, &tests[cnt].input[i], 1); -+ MD5_Final (sum, &ctx); - if (memcmp (tests[cnt].result, sum, 16)) - { - report_failure (cnt, "byte by byte", tests[cnt].result, sum); -@@ -108,10 +108,10 @@ main (void) - . */ - char buf[1000]; - memset (buf, 'a', sizeof (buf)); -- md5_init_ctx (&ctx); -+ MD5_Init (&ctx); - for (i = 0; i < 1000; ++i) -- md5_process_bytes (buf, sizeof (buf), &ctx); -- md5_finish_ctx (&ctx, sum); -+ MD5_Update (&ctx, buf, sizeof (buf)); -+ MD5_Final (sum, &ctx); - static const char expected[64] = - "\x77\x07\xd6\xae\x4e\x02\x7c\x70\xee\xa2\xa9\x35\xc2\x29\x6f\x21"; - if (memcmp (expected, sum, 16) != 0) - -From 6fcd7eb3324b67b22b39626cf587013437707efc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 22 Oct 2018 14:16:22 +0200 -Subject: [PATCH 11/17] Use unmodified md4 implementation from Alexander - Peslyak. - ---- - alg-md4.c | 428 +++++++++++++++++++++++++------------------------ - alg-md4.h | 61 +++---- - crypt-nthash.c | 24 +-- - crypt-port.h | 6 +- - test-alg-md4.c | 18 +-- - 5 files changed, 278 insertions(+), 259 deletions(-) - -diff --git a/alg-md4.c b/alg-md4.c -index c1c4075..482b6f4 100644 ---- a/alg-md4.c -+++ b/alg-md4.c -@@ -1,256 +1,270 @@ - /* -- * MD4 (RFC-1320) message digest. -- * Modified from MD5 code by Andrey Panin -+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. -+ * MD4 Message-Digest Algorithm (RFC 1320). - * -- * Written by Solar Designer in 2001, and placed in -- * the public domain. There's absolutely no warranty. -+ * Homepage: -+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 - * -- * This differs from Colin Plumb's older public domain implementation in -- * that no 32-bit integer data type is required, there's no compile-time -- * endianness configuration. -- * The primary goals are portability and ease of use. -+ * Author: -+ * Alexander Peslyak, better known as Solar Designer - * -- * This implementation is meant to be fast, but not as fast as possible. -- * Some known optimizations are not included to reduce source code size -- * and avoid compile-time configuration. -+ * This software was written by Alexander Peslyak in 2001. No copyright is -+ * claimed, and the software is hereby placed in the public domain. -+ * In case this attempt to disclaim copyright and place the software in the -+ * public domain is deemed null and void, then the software is -+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the -+ * general public under the following terms: -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted. -+ * -+ * There's ABSOLUTELY NO WARRANTY, express or implied. -+ * -+ * (This is a heavily cut-down "BSD license".) -+ * -+ * This differs from Colin Plumb's older public domain implementation in that -+ * no exactly 32-bit integer data type is required (any 32-bit or wider -+ * unsigned integer data type will do), there's no compile-time endianness -+ * configuration, and the function prototypes match OpenSSL's. No code from -+ * Colin Plumb's implementation has been reused; this comment merely compares -+ * the properties of the two independent implementations. -+ * -+ * The primary goals of this implementation are portability and ease of use. -+ * It is meant to be fast, but not as fast as possible. Some known -+ * optimizations are not included to reduce source code size and avoid -+ * compile-time configuration. - */ - - #include "crypt-port.h" --#include "alg-md4.h" --#include "byteorder.h" - - #if INCLUDE_nthash - -+#include "alg-md4.h" -+ - /* - * The basic MD4 functions. -+ * -+ * F and G are optimized compared to their RFC 1320 definitions, with the -+ * optimization for F borrowed from Colin Plumb's MD5 implementation. - */ --#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) --#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) --#define H(x, y, z) ((x) ^ (y) ^ (z)) -+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -+#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) -+#define H(x, y, z) ((x) ^ (y) ^ (z)) - - /* -- * The MD4 transformation for all four rounds. -+ * The MD4 transformation for all three rounds. - */ - #define STEP(f, a, b, c, d, x, s) \ -- (a) += f((b), (c), (d)) + (x); \ -- (a) = ((a) << (s)) | ((a) >> (32 - (s))) -+ (a) += f((b), (c), (d)) + (x); \ -+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); - - /* -- * SET reads 4 input bytes in little-endian byte order and stores them -- * in a properly aligned word in host byte order. -+ * SET reads 4 input bytes in little-endian byte order and stores them in a -+ * properly aligned word in host byte order. - * -- * The check for little-endian architectures which tolerate unaligned -- * memory accesses is just an optimization. Nothing will break if it -- * doesn't work. -+ * The check for little-endian architectures that tolerate unaligned memory -+ * accesses is just an optimization. Nothing will break if it fails to detect -+ * a suitable architecture. -+ * -+ * Unfortunately, this optimization may be a C strict aliasing rules violation -+ * if the caller's data buffer has effective type that cannot be aliased by -+ * MD4_u32plus. In practice, this problem may occur if these MD4 routines are -+ * inlined into a calling function, or with future and dangerously advanced -+ * link-time optimizations. For the time being, keeping these MD4 routines in -+ * their own translation unit avoids the problem. - */ -+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -+#define SET(n) \ -+ (*(const MD4_u32plus *)&ptr[(n) * 4]) -+#define GET(n) \ -+ SET(n) -+#else - #define SET(n) \ -- (ctx->block[(n)] = le32_to_cpu (&ptr[(n) * 4])) -+ (ctx->block[(n)] = \ -+ (MD4_u32plus)ptr[(n) * 4] | \ -+ ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \ -+ ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \ -+ ((MD4_u32plus)ptr[(n) * 4 + 3] << 24)) - #define GET(n) \ -- (ctx->block[(n)]) -+ (ctx->block[(n)]) -+#endif - - /* -- * This processes one or more 64-byte data blocks, but does NOT update -- * the bit counters. There're no alignment requirements. -+ * This processes one or more 64-byte data blocks, but does NOT update the bit -+ * counters. There are no alignment requirements. - */ --static const unsigned char * --body (struct md4_ctx *ctx, const unsigned char *data, size_t size) -+static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) - { -- const unsigned char *ptr; -- uint32_t a, b, c, d; -- uint32_t saved_a, saved_b, saved_c, saved_d; -- -- ptr = data; -- -- a = ctx->a; -- b = ctx->b; -- c = ctx->c; -- d = ctx->d; -- -- do -- { -- saved_a = a; -- saved_b = b; -- saved_c = c; -- saved_d = d; -- -- /* Round 1 */ -- STEP(F, a, b, c, d, SET( 0), 3); -- STEP(F, d, a, b, c, SET( 1), 7); -- STEP(F, c, d, a, b, SET( 2), 11); -- STEP(F, b, c, d, a, SET( 3), 19); -- -- STEP(F, a, b, c, d, SET( 4), 3); -- STEP(F, d, a, b, c, SET( 5), 7); -- STEP(F, c, d, a, b, SET( 6), 11); -- STEP(F, b, c, d, a, SET( 7), 19); -- -- STEP(F, a, b, c, d, SET( 8), 3); -- STEP(F, d, a, b, c, SET( 9), 7); -- STEP(F, c, d, a, b, SET(10), 11); -- STEP(F, b, c, d, a, SET(11), 19); -- -- STEP(F, a, b, c, d, SET(12), 3); -- STEP(F, d, a, b, c, SET(13), 7); -- STEP(F, c, d, a, b, SET(14), 11); -- STEP(F, b, c, d, a, SET(15), 19); -- -- /* Round 2 */ -- STEP(G, a, b, c, d, GET( 0) + 0x5A827999, 3); -- STEP(G, d, a, b, c, GET( 4) + 0x5A827999, 5); -- STEP(G, c, d, a, b, GET( 8) + 0x5A827999, 9); -- STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13); -- -- STEP(G, a, b, c, d, GET( 1) + 0x5A827999, 3); -- STEP(G, d, a, b, c, GET( 5) + 0x5A827999, 5); -- STEP(G, c, d, a, b, GET( 9) + 0x5A827999, 9); -- STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13); -- -- STEP(G, a, b, c, d, GET( 2) + 0x5A827999, 3); -- STEP(G, d, a, b, c, GET( 6) + 0x5A827999, 5); -- STEP(G, c, d, a, b, GET(10) + 0x5A827999, 9); -- STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13); -- -- STEP(G, a, b, c, d, GET( 3) + 0x5A827999, 3); -- STEP(G, d, a, b, c, GET( 7) + 0x5A827999, 5); -- STEP(G, c, d, a, b, GET(11) + 0x5A827999, 9); -- STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13); -- -- /* Round 3 */ -- STEP(H, a, b, c, d, GET( 0) + 0x6ED9EBA1, 3); -- STEP(H, d, a, b, c, GET( 8) + 0x6ED9EBA1, 9); -- STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11); -- STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15); -- -- STEP(H, a, b, c, d, GET( 2) + 0x6ED9EBA1, 3); -- STEP(H, d, a, b, c, GET(10) + 0x6ED9EBA1, 9); -- STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11); -- STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15); -- -- STEP(H, a, b, c, d, GET( 1) + 0x6ED9EBA1, 3); -- STEP(H, d, a, b, c, GET( 9) + 0x6ED9EBA1, 9); -- STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11); -- STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15); -- -- STEP(H, a, b, c, d, GET( 3) + 0x6ED9EBA1, 3); -- STEP(H, d, a, b, c, GET(11) + 0x6ED9EBA1, 9); -- STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11); -- STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15); -- -- a += saved_a; -- b += saved_b; -- c += saved_c; -- d += saved_d; -- -- ptr += 64; -- } -- while (size -= 64); -- -- ctx->a = a; -- ctx->b = b; -- ctx->c = c; -- ctx->d = d; -- -- return ptr; -+ const unsigned char *ptr; -+ MD4_u32plus a, b, c, d; -+ MD4_u32plus saved_a, saved_b, saved_c, saved_d; -+ const MD4_u32plus ac1 = 0x5a827999, ac2 = 0x6ed9eba1; -+ -+ ptr = (const unsigned char *)data; -+ -+ a = ctx->a; -+ b = ctx->b; -+ c = ctx->c; -+ d = ctx->d; -+ -+ do { -+ saved_a = a; -+ saved_b = b; -+ saved_c = c; -+ saved_d = d; -+ -+/* Round 1 */ -+ STEP(F, a, b, c, d, SET(0), 3) -+ STEP(F, d, a, b, c, SET(1), 7) -+ STEP(F, c, d, a, b, SET(2), 11) -+ STEP(F, b, c, d, a, SET(3), 19) -+ STEP(F, a, b, c, d, SET(4), 3) -+ STEP(F, d, a, b, c, SET(5), 7) -+ STEP(F, c, d, a, b, SET(6), 11) -+ STEP(F, b, c, d, a, SET(7), 19) -+ STEP(F, a, b, c, d, SET(8), 3) -+ STEP(F, d, a, b, c, SET(9), 7) -+ STEP(F, c, d, a, b, SET(10), 11) -+ STEP(F, b, c, d, a, SET(11), 19) -+ STEP(F, a, b, c, d, SET(12), 3) -+ STEP(F, d, a, b, c, SET(13), 7) -+ STEP(F, c, d, a, b, SET(14), 11) -+ STEP(F, b, c, d, a, SET(15), 19) -+ -+/* Round 2 */ -+ STEP(G, a, b, c, d, GET(0) + ac1, 3) -+ STEP(G, d, a, b, c, GET(4) + ac1, 5) -+ STEP(G, c, d, a, b, GET(8) + ac1, 9) -+ STEP(G, b, c, d, a, GET(12) + ac1, 13) -+ STEP(G, a, b, c, d, GET(1) + ac1, 3) -+ STEP(G, d, a, b, c, GET(5) + ac1, 5) -+ STEP(G, c, d, a, b, GET(9) + ac1, 9) -+ STEP(G, b, c, d, a, GET(13) + ac1, 13) -+ STEP(G, a, b, c, d, GET(2) + ac1, 3) -+ STEP(G, d, a, b, c, GET(6) + ac1, 5) -+ STEP(G, c, d, a, b, GET(10) + ac1, 9) -+ STEP(G, b, c, d, a, GET(14) + ac1, 13) -+ STEP(G, a, b, c, d, GET(3) + ac1, 3) -+ STEP(G, d, a, b, c, GET(7) + ac1, 5) -+ STEP(G, c, d, a, b, GET(11) + ac1, 9) -+ STEP(G, b, c, d, a, GET(15) + ac1, 13) -+ -+/* Round 3 */ -+ STEP(H, a, b, c, d, GET(0) + ac2, 3) -+ STEP(H, d, a, b, c, GET(8) + ac2, 9) -+ STEP(H, c, d, a, b, GET(4) + ac2, 11) -+ STEP(H, b, c, d, a, GET(12) + ac2, 15) -+ STEP(H, a, b, c, d, GET(2) + ac2, 3) -+ STEP(H, d, a, b, c, GET(10) + ac2, 9) -+ STEP(H, c, d, a, b, GET(6) + ac2, 11) -+ STEP(H, b, c, d, a, GET(14) + ac2, 15) -+ STEP(H, a, b, c, d, GET(1) + ac2, 3) -+ STEP(H, d, a, b, c, GET(9) + ac2, 9) -+ STEP(H, c, d, a, b, GET(5) + ac2, 11) -+ STEP(H, b, c, d, a, GET(13) + ac2, 15) -+ STEP(H, a, b, c, d, GET(3) + ac2, 3) -+ STEP(H, d, a, b, c, GET(11) + ac2, 9) -+ STEP(H, c, d, a, b, GET(7) + ac2, 11) -+ STEP(H, b, c, d, a, GET(15) + ac2, 15) -+ -+ a += saved_a; -+ b += saved_b; -+ c += saved_c; -+ d += saved_d; -+ -+ ptr += 64; -+ } while (size -= 64); -+ -+ ctx->a = a; -+ ctx->b = b; -+ ctx->c = c; -+ ctx->d = d; -+ -+ return ptr; - } - --/* Put result from CTX in first 16 bytes following RESBUF. The result -- will be in little endian byte order. */ --static void * --md4_read_ctx (struct md4_ctx *ctx, void *resbuf) -+void MD4_Init(MD4_CTX *ctx) - { -- unsigned char *buf = resbuf; -- cpu_to_le32 (buf + 0, ctx->a); -- cpu_to_le32 (buf + 4, ctx->b); -- cpu_to_le32 (buf + 8, ctx->c); -- cpu_to_le32 (buf + 12, ctx->d); -- XCRYPT_SECURE_MEMSET (ctx, sizeof(struct md4_ctx)); -- return resbuf; -+ ctx->a = 0x67452301; -+ ctx->b = 0xefcdab89; -+ ctx->c = 0x98badcfe; -+ ctx->d = 0x10325476; -+ -+ ctx->lo = 0; -+ ctx->hi = 0; - } - --void --md4_init_ctx (struct md4_ctx *ctx) -+void MD4_Update(MD4_CTX *ctx, const void *data, size_t size) - { -- ctx->a = 0x67452301; -- ctx->b = 0xefcdab89; -- ctx->c = 0x98badcfe; -- ctx->d = 0x10325476; -+ MD4_u32plus saved_lo; -+ unsigned long used, available; - -- ctx->lo = 0; -- ctx->hi = 0; --} -+ saved_lo = ctx->lo; -+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) -+ ctx->hi++; -+ ctx->hi += (MD4_u32plus) size >> 29; - --void --md4_process_bytes (const void *buffer, struct md4_ctx *ctx, size_t size) --{ -- uint32_t saved_lo; -- size_t used, free; -- -- saved_lo = ctx->lo; -- if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) -- ctx->hi++; -- ctx->hi += (uint32_t)(size >> 29); -- -- used = saved_lo & 0x3f; -- -- if (used) -- { -- free = 64 - used; -- -- if (size < free) -- { -- memcpy(&ctx->buffer[used], buffer, size); -- return; -- } -- -- memcpy(&ctx->buffer[used], buffer, free); -- buffer = (const unsigned char *) buffer + free; -- size -= free; -- body(ctx, ctx->buffer, 64); -- } -- -- if (size >= 64) -- { -- buffer = body(ctx, buffer, size & ~(uint32_t)0x3f); -- size &= 0x3f; -- } -- -- memcpy(ctx->buffer, buffer, size); -+ used = saved_lo & 0x3f; -+ -+ if (used) { -+ available = 64 - used; -+ -+ if (size < available) { -+ memcpy(&ctx->buffer[used], data, size); -+ return; -+ } -+ -+ memcpy(&ctx->buffer[used], data, available); -+ data = (const unsigned char *)data + available; -+ size -= available; -+ body(ctx, ctx->buffer, 64); -+ } -+ -+ if (size >= 64) { -+ data = body(ctx, data, size & ~(unsigned long)0x3f); -+ size &= 0x3f; -+ } -+ -+ memcpy(ctx->buffer, data, size); - } - --void * --md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) -+#define OUT(dst, src) \ -+ (dst)[0] = (unsigned char)(src); \ -+ (dst)[1] = (unsigned char)((src) >> 8); \ -+ (dst)[2] = (unsigned char)((src) >> 16); \ -+ (dst)[3] = (unsigned char)((src) >> 24); -+ -+void MD4_Final(uint8_t result[16], MD4_CTX *ctx) - { -- size_t used, free; -+ unsigned long used, available; -+ -+ used = ctx->lo & 0x3f; - -- used = ctx->lo & 0x3f; -+ ctx->buffer[used++] = 0x80; - -- ctx->buffer[used++] = 0x80; -+ available = 64 - used; - -- free = 64 - used; -+ if (available < 8) { -+ XCRYPT_SECURE_MEMSET(&ctx->buffer[used], available); -+ body(ctx, ctx->buffer, 64); -+ used = 0; -+ available = 64; -+ } - -- if (free < 8) -- { -- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free); -- body(ctx, ctx->buffer, 64); -- used = 0; -- free = 64; -- } -+ XCRYPT_SECURE_MEMSET(&ctx->buffer[used], available - 8); - -- XCRYPT_SECURE_MEMSET (&ctx->buffer[used], free - 8); -+ ctx->lo <<= 3; -+ OUT(&ctx->buffer[56], ctx->lo) -+ OUT(&ctx->buffer[60], ctx->hi) - -- ctx->lo <<= 3; -- ctx->buffer[56] = (unsigned char)((ctx->lo) & 0xff); -- ctx->buffer[57] = (unsigned char)((ctx->lo >> 8) & 0xff); -- ctx->buffer[58] = (unsigned char)((ctx->lo >> 16) & 0xff); -- ctx->buffer[59] = (unsigned char)((ctx->lo >> 24) & 0xff); -- ctx->buffer[60] = (unsigned char)((ctx->hi) & 0xff); -- ctx->buffer[61] = (unsigned char)((ctx->hi >> 8) & 0xff); -- ctx->buffer[62] = (unsigned char)((ctx->hi >> 16) & 0xff); -- ctx->buffer[63] = (unsigned char)((ctx->hi >> 24) & 0xff); -+ body(ctx, ctx->buffer, 64); - -- body(ctx, ctx->buffer, 64); -+ OUT(&result[0], ctx->a) -+ OUT(&result[4], ctx->b) -+ OUT(&result[8], ctx->c) -+ OUT(&result[12], ctx->d) - -- return md4_read_ctx (ctx, resbuf); -+ XCRYPT_SECURE_MEMSET(ctx, sizeof(*ctx)); - } - - #endif -diff --git a/alg-md4.h b/alg-md4.h -index 4c3e29c..473930e 100644 ---- a/alg-md4.h -+++ b/alg-md4.h -@@ -1,38 +1,43 @@ - /* -- * This is an implementation of the RSA Data Security, Inc. -- * MD4 Message-Digest Algorithm. -+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. -+ * MD4 Message-Digest Algorithm (RFC 1320). - * -- * Written by Solar Designer in 2001, and placed in -- * the public domain. See md4.c for more information. -+ * Homepage: -+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 -+ * -+ * Author: -+ * Alexander Peslyak, better known as Solar Designer -+ * -+ * This software was written by Alexander Peslyak in 2001. No copyright is -+ * claimed, and the software is hereby placed in the public domain. -+ * In case this attempt to disclaim copyright and place the software in the -+ * public domain is deemed null and void, then the software is -+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the -+ * general public under the following terms: -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted. -+ * -+ * There's ABSOLUTELY NO WARRANTY, express or implied. -+ * -+ * See md4.c for more information. - */ - - #ifndef _CRYPT_ALG_MD4_H - #define _CRYPT_ALG_MD4_H 1 - --#include --#include -- --/* Structure to save state of computation between the single steps. */ --struct md4_ctx --{ -- uint32_t lo, hi; -- uint32_t a, b, c, d; -- unsigned char buffer[64]; -- uint32_t block[16]; --}; -- --/* Initialize structure containing state of computation. -- (RFC 1320, 3.3: Step 3) */ --extern void md4_init_ctx (struct md4_ctx *ctx); -+/* Any 32-bit or wider unsigned integer data type will do */ -+typedef uint32_t MD4_u32plus; - --/* Starting with the result of former calls of this function (or the -- initialization function) update the context for the next LEN bytes -- starting at BUFFER. LEN does not need to be a multiple of 64. */ --extern void md4_process_bytes (const void *buffer, struct md4_ctx *ctx, size_t size); -+typedef struct { -+ MD4_u32plus lo, hi; -+ MD4_u32plus a, b, c, d; -+ uint8_t buffer[64]; -+ MD4_u32plus block[16]; -+} MD4_CTX; - --/* Process the remaining bytes in the buffer and write the finalized -- hash to RESBUF, which should point to 16 bytes of storage. All -- data written to CTX is erased before returning from the function. */ --extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf); -+extern void MD4_Init(MD4_CTX *ctx); -+extern void MD4_Update(MD4_CTX *ctx, const void *data, size_t size); -+extern void MD4_Final(uint8_t result[16], MD4_CTX *ctx); - --#endif -+#endif /* alg-md4.h */ -diff --git a/crypt-nthash.c b/crypt-nthash.c -index 5a715de..db6f17e 100644 ---- a/crypt-nthash.c -+++ b/crypt-nthash.c -@@ -61,10 +61,10 @@ crypt_nthash_rn (const char *phrase, size_t ARG_UNUSED (phr_size), - uint16_t unipw[128]; - unsigned char hash[16]; - const char *s; -- struct md4_ctx *ctx = scratch; -+ MD4_CTX *ctx = scratch; - - if ((out_size < 4 + 32) || -- (scr_size < sizeof (struct md4_ctx))) -+ (scr_size < sizeof (MD4_CTX))) - { - errno = ERANGE; - return; -@@ -83,9 +83,9 @@ crypt_nthash_rn (const char *phrase, size_t ARG_UNUSED (phr_size), - unipw[unipwLen++] = htons((uint16_t)(*s << 8)); - - /* Compute MD4 of Unicode password */ -- md4_init_ctx (ctx); -- md4_process_bytes ((unsigned char *)unipw, ctx, unipwLen*sizeof(uint16_t)); -- md4_finish_ctx (ctx, hash); -+ MD4_Init (ctx); -+ MD4_Update (ctx, unipw, unipwLen*sizeof(uint16_t)); -+ MD4_Final (hash, ctx); - - output = (uint8_t *)stpcpy ((char *)output, magic); - *output++ = '$'; -@@ -111,7 +111,7 @@ gensalt_nthash_rn (unsigned long count, - size_t o_size) - { - static const char *salt = "$3$__not_used__"; -- struct md4_ctx ctx; -+ MD4_CTX ctx; - unsigned char hashbuf[16]; - char hashstr[14 + 1]; - unsigned long i; -@@ -131,15 +131,15 @@ gensalt_nthash_rn (unsigned long count, - return; - } - -- md4_init_ctx (&ctx); -+ MD4_Init (&ctx); - for (i = 0; i < 20; i++) - { -- md4_process_bytes (salt, &ctx, (i % 15) + 1); -- md4_process_bytes (rbytes, &ctx, nrbytes); -- md4_process_bytes (salt, &ctx, 15); -- md4_process_bytes (salt, &ctx, 15 - (i % 15)); -+ MD4_Update (&ctx, salt, (i % 15) + 1); -+ MD4_Update (&ctx, rbytes, nrbytes); -+ MD4_Update (&ctx, salt, 15); -+ MD4_Update (&ctx, salt, 15 - (i % 15)); - } -- md4_finish_ctx (&ctx, &hashbuf); -+ MD4_Final (hashbuf, &ctx); - - for (i = 0; i < 7; i++) - sprintf (&(hashstr[i * 2]), "%02x", hashbuf[i]); -diff --git a/crypt-port.h b/crypt-port.h -index 2571c94..fa30e8e 100644 ---- a/crypt-port.h -+++ b/crypt-port.h -@@ -241,9 +241,9 @@ _xcrypt_strcpy_or_abort (void *dst, const size_t d_size, - #endif - - #if INCLUDE_nthash --#define md4_finish_ctx _crypt_md4_finish_ctx --#define md4_init_ctx _crypt_md4_init_ctx --#define md4_process_bytes _crypt_md4_process_bytes -+#define MD4_Init _crypt_MD4_Init -+#define MD4_Update _crypt_MD4_Update -+#define MD4_Final _crypt_MD4_Final - #endif - - #if INCLUDE_md5 || INCLUDE_sunmd5 -diff --git a/test-alg-md4.c b/test-alg-md4.c -index 1b1b828..595e0bb 100644 ---- a/test-alg-md4.c -+++ b/test-alg-md4.c -@@ -45,7 +45,7 @@ static const struct - - static void - report_failure(int n, const char *tag, -- const char expected[16], const char actual[16]) -+ const char expected[16], uint8_t actual[16]) - { - int i; - printf ("FAIL: test %d (%s):\n exp:", n, tag); -@@ -69,27 +69,27 @@ report_failure(int n, const char *tag, - int - main (void) - { -- struct md4_ctx ctx; -- char sum[16]; -+ MD4_CTX ctx; -+ uint8_t sum[16]; - int result = 0; - int cnt; - int i; - - for (cnt = 0; cnt < (int) ARRAY_SIZE (tests); ++cnt) - { -- md4_init_ctx (&ctx); -- md4_process_bytes ((const unsigned char*)tests[cnt].input, &ctx, strlen (tests[cnt].input)); -- md4_finish_ctx (&ctx, (unsigned char*)sum); -+ MD4_Init (&ctx); -+ MD4_Update (&ctx, tests[cnt].input, strlen (tests[cnt].input)); -+ MD4_Final (sum, &ctx); - if (memcmp (tests[cnt].result, sum, 16)) - { - report_failure (cnt, "all at once", tests[cnt].result, sum); - result = 1; - } - -- md4_init_ctx (&ctx); -+ MD4_Init (&ctx); - for (i = 0; tests[cnt].input[i] != '\0'; ++i) -- md4_process_bytes ((const unsigned char*)&tests[cnt].input[i], &ctx, 1); -- md4_finish_ctx (&ctx, (unsigned char*)sum); -+ MD4_Update (&ctx, &tests[cnt].input[i], 1); -+ MD4_Final (sum, &ctx); - if (memcmp (tests[cnt].result, sum, 16)) - { - report_failure (cnt, "byte by byte", tests[cnt].result, sum); - -From 6fc8102f7727f8e4115a87070d2e4a36b55ea1bc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 22 Oct 2018 19:51:57 +0200 -Subject: [PATCH 12/17] Fix -Wcast-align. - ---- - alg-md4.c | 2 +- - alg-md5.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/alg-md4.c b/alg-md4.c -index 482b6f4..a6e1072 100644 ---- a/alg-md4.c -+++ b/alg-md4.c -@@ -73,7 +73,7 @@ - * link-time optimizations. For the time being, keeping these MD4 routines in - * their own translation unit avoids the problem. - */ --#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -+#if 0 /* defined(__i386__) || defined(__x86_64__) || defined(__vax__) */ - #define SET(n) \ - (*(const MD4_u32plus *)&ptr[(n) * 4]) - #define GET(n) \ -diff --git a/alg-md5.c b/alg-md5.c -index 8382b98..5502539 100644 ---- a/alg-md5.c -+++ b/alg-md5.c -@@ -77,7 +77,7 @@ - * link-time optimizations. For the time being, keeping these MD5 routines in - * their own translation unit avoids the problem. - */ --#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -+#if 0 /* defined(__i386__) || defined(__x86_64__) || defined(__vax__) */ - #define SET(n) \ - (*(const MD5_u32plus *)&ptr[(n) * 4]) - #define GET(n) \ - -From cc50dde05be214caace8af493fe869832a1d3d68 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Mon, 22 Oct 2018 20:03:03 +0200 -Subject: [PATCH 13/17] Remove unused file. - ---- - m4/.git_keep_dir | 0 - 1 file changed, 0 insertions(+), 0 deletions(-) - delete mode 100644 m4/.git_keep_dir - -diff --git a/m4/.git_keep_dir b/m4/.git_keep_dir -deleted file mode 100644 -index e69de29..0000000 - -From 1cf317228655013c516090a20e70d81656516580 Mon Sep 17 00:00:00 2001 -From: Vitaly Chikunov -Date: Wed, 24 Oct 2018 05:24:47 +0300 -Subject: [PATCH 14/17] yescrypt: Add more tests. - -Test that crypt() with hashed password in place of settings works the -same as settings. ---- - test-crypt-yescrypt.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/test-crypt-yescrypt.c b/test-crypt-yescrypt.c -index a635f94..9d67b92 100644 ---- a/test-crypt-yescrypt.c -+++ b/test-crypt-yescrypt.c -@@ -43,8 +43,16 @@ test(const char *p, const char *s, const char *m) - int - main (void) - { -- int result = test("pleaseletmein", "$y$jD5.7$LdJMENpBABJJ3hIHjB1Bi.", -- "$y$jD5.7$LdJMENpBABJJ3hIHjB1Bi.$HboGM6qPrsK.StKYGt6KErmUYtioHreJd98oIugoNB6"); -+ int result = 0; -+ -+#define YSETTINGS "$y$jD5.7$LdJMENpBABJJ3hIHjB1Bi." -+#define YHASHPART "HboGM6qPrsK.StKYGt6KErmUYtioHreJd98oIugoNB6" -+#define YFULLHASH YSETTINGS "$" YHASHPART -+ result |= test("pleaseletmein", YSETTINGS, YFULLHASH); -+ result |= test("pleaseletmein", YFULLHASH, YFULLHASH); -+ result |= test("pleaseletmein", YSETTINGS "$", YFULLHASH); -+ result |= test("pleaseletmein", YSETTINGS "$garbage", YFULLHASH); -+ - result |= test("", "$y$jD5.7$", "$y$jD5.7$$JD8dsR.nt1ty0ltQ2HHwauaDRoOUIEaA5i.vpj2nyL."); - result |= test("", "$y$jD5.7$$", "$y$jD5.7$$JD8dsR.nt1ty0ltQ2HHwauaDRoOUIEaA5i.vpj2nyL."); - - -From 232b217faba35064ca30120751f788d649cb3020 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Wed, 24 Oct 2018 15:54:12 +0200 -Subject: [PATCH 15/17] Use bzip2 and xz compression for distribution tarballs, - too. - ---- - Makefile.am | 2 +- - NEWS | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index e7d5c6d..8cb3807 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -4,7 +4,7 @@ - # Author: Thorsten Kukuk - # - --AUTOMAKE_OPTIONS = 1.14 gnits -+AUTOMAKE_OPTIONS = 1.14 gnits dist-bzip2 dist-xz - ACLOCAL_AMFLAGS = -I m4 - - AM_CFLAGS = $(WARN_CFLAGS) -diff --git a/NEWS b/NEWS -index e48b0d1..8af68ff 100644 ---- a/NEWS -+++ b/NEWS -@@ -10,6 +10,8 @@ Version 4.2.3 - sha512 implementation under the BSD license. - * Use md5 implementation from Alexander Peslyak. Thus we now have a - md5 implementation in the public domain. -+* 'make dist' now generates bzip2 and xz compressed tarballs along -+ with the default gzip compressed tarball. - - Version 4.2.2 - * Convert existing manpages to BSD mdoc format. - -From a17c2d75c5642d164e04748ddb93f8f426c7ed5c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Thu, 25 Oct 2018 13:47:04 +0200 -Subject: [PATCH 16/17] Add Badge for Coverity Scan. - ---- - README.md | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/README.md b/README.md -index 102127a..9a91ad5 100644 ---- a/README.md -+++ b/README.md -@@ -1,5 +1,6 @@ - [![Build Status](https://travis-ci.org/besser82/libxcrypt.svg?branch=develop)](https://travis-ci.org/besser82/libxcrypt) - [![codecov](https://codecov.io/gh/besser82/libxcrypt/branch/develop/graph/badge.svg)](https://codecov.io/gh/besser82/libxcrypt) -+[![Coverity Scan Build Status](https://scan.coverity.com/projects/17073/badge.svg)](https://scan.coverity.com/projects/besser82-libxcrypt) - - README for libxcrypt - ==================== - -From 8b1ff5c38f316bc301e57a5a307fd11b8984e494 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= -Date: Thu, 25 Oct 2018 14:06:01 +0200 -Subject: [PATCH 17/17] Add labels to TravisCI builds. - ---- - .travis.yml | 75 +++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 50 insertions(+), 25 deletions(-) - -diff --git a/.travis.yml b/.travis.yml -index acb186c..2e7a746 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -15,153 +15,178 @@ sudo: true - matrix: - fast_finish: true - include: -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, Codecov" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - CODECOV=1 -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, all hashes, obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" - - DISTCHECK=1 -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, all hashes, obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, all hashes, obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, all hashes, obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, all hashes, obsolete API, no failure-tokens" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-failure-tokens --enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, all hashes, obsolete API, no failure-tokens" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-failure-tokens --enable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, all hashes, obsolete API, no failure-tokens" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-failure-tokens --enable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, all hashes, obsolete API, no failure-tokens" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-failure-tokens --enable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, all hashes, no obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, all hashes, no obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, all hashes, no obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, all hashes, no obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=all" - - FCVER="latest" -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, strong hashes, no obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="rawhide" -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, strong hashes, no obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, strong hashes, no obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, strong hashes, no obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--disable-obsolete-api --enable-hashes=strong" - - FCVER="latest" -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, glibc hashes, obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=glibc" - - FCVER="rawhide" -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, glibc hashes, obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=glibc" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, glibc hashes, obsolete API" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=glibc" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, glibc hashes, obsolete API" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--enable-obsolete-api --enable-hashes=glibc" - - FCVER="latest" -- - compiler: gcc -+ - name: "Fedora Rawhide, GCC, glibc and strong hashes, obsolete API for glibc" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" - - FCVER="rawhide" -- - compiler: clang -+ - name: "Fedora Rawhide, Clang, glibc and strong hashes, obsolete API for glibc" -+ compiler: clang - os: linux - services: docker - env: - - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" - - FCVER="rawhide" -- - compiler: gcc -+ - name: "Fedora stable, GCC, glibc and strong hashes, obsolete API for glibc" -+ compiler: gcc - os: linux - services: docker - env: - - CONF="--enable-obsolete-api=glibc --enable-hashes=strong,glibc" - - FCVER="latest" -- - compiler: clang -+ - name: "Fedora stable, Clang, glibc and strong hashes, obsolete API for glibc" -+ compiler: clang - os: linux - services: docker - env: