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=56fc361c2d2....
Change: +%ifnarch %{power64}
Thanks.
Full change: ============
commit de4a76fef760e86a036f510ae412bfa477cb7f24 Author: Bjrn Esser besser82@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@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@fedoraproject.org - 4.2.2-1 - New upstream release
commit 56fc361c2d2d33ff6acdfa408af543367ae39954 Author: Bjrn Esser besser82@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@fedoraproject.org - 4.2.2-2 - Add patch updating to recent development version +- Run valgrind-memcheck
* Thu Oct 18 2018 Bjrn Esser besser82@fedoraproject.org - 4.2.2-1 - New upstream release
commit ea4ffe97b18e8cb8857b3398861b6eb4948236c8 Author: Bjrn Esser besser82@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@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@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@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@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@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@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@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@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@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@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@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@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@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/md... ++ * ++ * 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/md... ++ * ++ * 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@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@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@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/md... + * +- * 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@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/md... ++ * ++ * 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@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@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@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@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@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@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 @@ + [%5D(https://trav...) + [%5D(...) ++[%5D(https://scan.coverity...) + + README for libxcrypt + ==================== + +From 8b1ff5c38f316bc301e57a5a307fd11b8984e494 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= besser82@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/%%7Bname%7D 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@fedoraproject.org - 4.2.2-2 +- Add patch updating to recent development version + * Thu Oct 18 2018 Bjrn Esser besser82@fedoraproject.org - 4.2.2-1 - New upstream release