The package rpms/libxcrypt.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/libxcrypt.git/commit/?id=56fc361c....
Change:
+%ifnarch %{power64}
Thanks.
Full change:
============
commit de4a76fef760e86a036f510ae412bfa477cb7f24
Author: Bjrn Esser <besser82(a)fedoraproject.org>
Date: Thu Oct 25 16:40:55 2018 +0200
Use bootstrap script
diff --git a/libxcrypt.spec b/libxcrypt.spec
index 43a9a12..dbd40e0 100644
--- a/libxcrypt.spec
+++ b/libxcrypt.spec
@@ -216,7 +216,7 @@ discouraged.
%prep
%autosetup -p 1
-%{_bindir}/autoreconf -fiv
+./bootstrap
%{__mkdir_p} %{_vpath_builddir}{,-compat}
@@ -338,6 +338,7 @@ done
* Thu Oct 25 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-2
- Add patch updating to recent development version
- Run valgrind-memcheck
+- Use bootstrap script
* Thu Oct 18 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-1
- New upstream release
commit 56fc361c2d2d33ff6acdfa408af543367ae39954
Author: Bjrn Esser <besser82(a)fedoraproject.org>
Date: Thu Oct 25 16:34:44 2018 +0200
Run valgrind-memcheck
diff --git a/libxcrypt.spec b/libxcrypt.spec
index 10749a5..43a9a12 100644
--- a/libxcrypt.spec
+++ b/libxcrypt.spec
@@ -6,6 +6,15 @@
#endif
+# Run memcheck?
+# Valgrind does not work well on %%{power64} arches.
+%ifnarch %{power64}
+%bcond_without memcheck
+%else
+%bcond_with memcheck
+%endif
+
+
# Shared object version of libcrypt.
%if %{with new_api}
%global soc 2
@@ -48,6 +57,11 @@
--enable-shared \\\
--enable-static \\\
--disable-failure-tokens \\\
+%if %{with memcheck} \
+ --enable-valgrind \\\
+%else \
+ --disable-valgrind \\\
+%endif \
--srcdir=.. \\\
--with-pkgconfigdir=%{_libdir}/pkgconfig
@@ -89,6 +103,9 @@ Patch0001:
%{url}/compare/v%{version}...develop.patch#/%{name}-%{version}-t
BuildRequires: fipscheck
BuildRequires: libtool
+%if %{with memcheck}
+BuildRequires: valgrind
+%endif
# We do not need to keep this forever.
%if %{without new_api} && (0%{?fedora} && 0%{?fedora} <= 31) ||
(0%{?rhel} && 0%{?rhel} <= 10)
@@ -260,6 +277,16 @@ for dir in %{_vpath_builddir}; do
echo "-----END TESTLOG: ${dir}-----";
exit $rc;
}
+%if %{with memcheck}
+ %make_build -C ${dir} check-valgrind-memcheck || \
+ {
+ rc=$?;
+ echo "-----BEGIN TESTLOG: ${dir}-----";
+ %{__cat} ${dir}/test-suite-memcheck.log;
+ echo "-----END TESTLOG: ${dir}-----";
+ exit $rc;
+ }
+%endif
done
@@ -310,6 +337,7 @@ done
%changelog
* Thu Oct 25 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-2
- Add patch updating to recent development version
+- Run valgrind-memcheck
* Thu Oct 18 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-1
- New upstream release
commit ea4ffe97b18e8cb8857b3398861b6eb4948236c8
Author: Bjrn Esser <besser82(a)fedoraproject.org>
Date: Thu Oct 25 16:28:21 2018 +0200
Add patch updating to recent development version
diff --git a/libxcrypt-4.2.2-to_develop.patch b/libxcrypt-4.2.2-to_develop.patch
new file mode 100644
index 0000000..d42e74c
--- /dev/null
+++ b/libxcrypt-4.2.2-to_develop.patch
@@ -0,0 +1,3945 @@
+From 9bae80381beabc1b08b0fd89d2a4e6e15e3e5da0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82(a)fedoraproject.org>
+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
+ <
https://github.com/besser82/libxcrypt/issues>.
+
++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?= <besser82(a)fedoraproject.org>
+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
+ <
https://github.com/besser82/libxcrypt/issues>.
+
+ 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 Bjrn Esser <besser82(a)fedoraproject.org>
++#
++# 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?= <besser82(a)fedoraproject.org>
+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
+ <
https://github.com/besser82/libxcrypt/issues>.
+
+ 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 <zackw(a)panix.com>
+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
+- <
https://pthree.org/2016/06/28/lets-talk-password-hashing/>
+- * 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 <
https://www.tarsnap.com/scrypt.html>
+- * Argon2 <
https://password-hashing.net/>
+- * ...?
+-
+- * 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 isnt wired up to autoconf
++ * possibly this should just be removed; does anything have
++ `posix_memalign` but not `mmap`? its 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 <
https://password-hashing.net/>
++ * ...?
++
++* 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 cant be changed without breaking existing stored hashes)
++ * relevant benchmarking at
++ <
https://pthree.org/2016/06/28/lets-talk-password-hashing/>
++ * 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 its 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 dont 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 yescrypts tunable parameters and ROM
++ feature, in a way thats generic enough that we could also use it
++ for e.g. Argon2s 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?= <besser82(a)fedoraproject.org>
+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?= <besser82(a)fedoraproject.org>
+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 @@
+ <
https://www.gnu.org/licenses/>. */
+
+ #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 @@
+ <
https://www.gnu.org/licenses/>. */
+
+ #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 <zackw at panix.com> 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 <errno.h>
+ #include <stdio.h>
+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 <stdio.h>
+
+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 <stdio.h>
+
+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 <errno.h>
+ #include <stdio.h>
+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 <stdio.h>
+
+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 <stdio.h>
+
+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 <stdio.h>
+
+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 <stdio.h>
+ #include <stdlib.h>
+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 <stdio.h>
+
+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 <errno.h>
+ #include <stdio.h>
+
+From a5f8acd51acb267d989ea3375ab17e29a0857059 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82(a)fedoraproject.org>
+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?= <besser82(a)fedoraproject.org>
+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?= <besser82(a)fedoraproject.org>
+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, Bjrn 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
+- <
https://www.gnu.org/licenses/>. */
++#include "alg-sha512.h"
++#include "alg-yescrypt-sysendian.h"
+
+-/* Written by Ulrich Drepper <drepper(a)redhat.com>, 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
+- <
https://www.gnu.org/licenses/>. */
+-
+-#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 <stddef.h>
++#include <stdint.h>
++
++/*
++ * 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 <sys/endian.h>. */
+ #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?= <besser82(a)fedoraproject.org>
+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
+- <
https://www.gnu.org/licenses/>. */
+-
+-/* Written by Ulrich Drepper <drepper(a)gnu.ai.mit.edu>, 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...
++ *
++ * Author:
++ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
++ *
++ * 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
+- <
https://www.gnu.org/licenses/>. */
++/*
++ * 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...
++ *
++ * Author:
++ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
++ *
++ * 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)
+ <
https://www.nist.gov/itl/ssd/software-quality-group/nsrl-test-data>. */
+ 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?= <besser82(a)fedoraproject.org>
+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 <pazke(a)donpac.ru>
++ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
++ * MD4 Message-Digest Algorithm (RFC 1320).
+ *
+- * Written by Solar Designer <solar(a)openwall.com> 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...
+ *
+- * 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 <solar at openwall.com>
+ *
+- * 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 <solar(a)openwall.com> 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...
++ *
++ * Author:
++ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
++ *
++ * 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 <stddef.h>
+-#include <stdint.h>
+-
+-/* 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?= <besser82(a)fedoraproject.org>
+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?= <besser82(a)fedoraproject.org>
+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 <vt(a)altlinux.org>
+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?= <besser82(a)fedoraproject.org>
+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 <kukuk(a)suse.de>
+ #
+
+-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?= <besser82(a)fedoraproject.org>
+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)](htt...
+
[![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...
+
+ README for libxcrypt
+ ====================
+
+From 8b1ff5c38f316bc301e57a5a307fd11b8984e494 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82(a)fedoraproject.org>
+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:
diff --git a/libxcrypt.spec b/libxcrypt.spec
index 92dd79a..10749a5 100644
--- a/libxcrypt.spec
+++ b/libxcrypt.spec
@@ -76,7 +76,7 @@ fi \
Name: libxcrypt
Version: 4.2.2
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Extended crypt library for DES, MD5, Blowfish and others
# For explicit license breakdown, see the
@@ -85,6 +85,8 @@ License: LGPLv2+ and BSD and Public Domain
URL:
https://github.com/besser82/%{name}
Source0: %{url}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+Patch0001:
%{url}/compare/v%{version}...develop.patch#/%{name}-%{version}-to_develop.patch
+
BuildRequires: fipscheck
BuildRequires: libtool
@@ -306,6 +308,9 @@ done
%changelog
+* Thu Oct 25 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-2
+- Add patch updating to recent development version
+
* Thu Oct 18 2018 Bjrn Esser <besser82(a)fedoraproject.org> - 4.2.2-1
- New upstream release